Building upon our previous tutorial, this guide takes real-time stock monitoring to the next level by adding dynamic graphs. Using Python's Matplotlib library, you can visualize stock price trends in real time, enhancing the application's usability and insights.
This tutorial demonstrates how to:
plot_graph
function updates a Matplotlib graph in real time, plotting stock prices against timestamps.update_graph
function runs on a separate thread, fetching stock data every 5 seconds without freezing the GUI.Here’s the complete code for the application:
# Import necessary libraries
import tkinter as tk # GUI framework
from tkinter import ttk # Themed widgets
import yfinance as yf # Yahoo Finance API for stock data
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # Embedding Matplotlib in Tkinter
import matplotlib.pyplot as plt # For plotting graphs
import threading # For creating and managing threads
import time # For delays
from datetime import datetime # For timestamps
# Global stop event to manage thread termination
stop_event = threading.Event()
# Dictionary of stock options with popular Indian stocks and indices
stock_options = {
"Reliance Industries": "RELIANCE.NS",
"Tata Consultancy Services (TCS)": "TCS.NS",
"Infosys": "INFY.NS",
"HDFC Bank": "HDFCBANK.NS",
"ICICI Bank": "ICICIBANK.NS",
"State Bank of India (SBI)": "SBIN.NS",
"Bharti Airtel": "BHARTIARTL.NS",
"Adani Enterprises": "ADANIENT.NS",
"NSE Nifty 50 Index": "^NSEI",
"BSE Sensex Index": "^BSESN"
}
# Function to fetch the stock price
def fetch_stock_price(ticker):
try:
# Create a Ticker object for the stock
stock = yf.Ticker(ticker)
# Fetch intraday data (1-minute interval) for the current day
data = stock.history(period="1d", interval="1m")
# Extract the most recent closing price
price = data['Close'].iloc[-1]
# Return the price rounded to 2 decimal places
return round(price, 2)
except Exception as e:
# Print the error message if data fetching fails
print(f"Error fetching data for {ticker}: {e}")
return None
# Function to create a new stock monitoring window
def create_stock_window(ticker, stock_name):
# Variables to store timestamps (x-axis) and prices (y-axis)
timestamps = []
prices = []
# Function to update the graph dynamically
def update_graph():
while not stop_event.is_set(): # Check if the stop event is not set
price = fetch_stock_price(ticker) # Fetch the current stock price
if price:
prices.append(price) # Append the price to the list
timestamps.append(datetime.now()) # Append the current timestamp
plot_graph() # Update the graph
time.sleep(5) # Wait for 5 seconds before fetching again
# Function to plot the graph
def plot_graph():
if not stop_event.is_set(): # Check if the stop event is not set
ax.clear() # Clear the existing plot
ax.plot(timestamps, prices, color='blue', label=f"{stock_name} Price")
ax.set_title(f"Real-Time Stock Price: {stock_name}")
ax.set_xlabel("Time") # Label for the x-axis
ax.set_ylabel("Price (INR)") # Label for the y-axis
ax.legend(loc="upper left") # Add a legend
ax.grid() # Add gridlines for better readability
ax.xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter("%H:%M:%S")) # Format x-axis timestamps
fig.autofmt_xdate() # Rotate x-axis labels for readability
canvas.draw() # Update the canvas with the new graph
# Function to handle closing of the stock monitoring window
def on_close():
plt.close(fig) # Close the Matplotlib figure
new_window.destroy() # Destroy the Tkinter window
# Create a new Tkinter window for the selected stock
new_window = tk.Toplevel(root)
new_window.title(f"{stock_name} Tracker")
new_window.geometry("800x600")
new_window.protocol("WM_DELETE_WINDOW", on_close) # Bind the close event
# Create a Matplotlib figure and embed it in the Tkinter window
fig, ax = plt.subplots()
canvas = FigureCanvasTkAgg(fig, master=new_window)
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
# Start a background thread to update the graph
tracking_thread = threading.Thread(target=update_graph, daemon=True)
tracking_thread.start()
# Function to handle closing of the main window
def on_main_close():
stop_event.set() # Signal all threads to stop
plt.close('all') # Close all Matplotlib figures
root.destroy() # Destroy the main Tkinter window
# Set up the main Tkinter window
root = tk.Tk()
root.title("Multi-Stock Monitoring System")
root.geometry("400x300")
root.protocol("WM_DELETE_WINDOW", on_main_close) # Bind the close event
# Create a dropdown menu to select stocks
stock_var = tk.StringVar(value="Reliance Industries") # Default selection
stock_dropdown = ttk.Combobox(
root, textvariable=stock_var, values=list(stock_options.keys()), state="readonly", font=("Arial", 12)
)
stock_dropdown.pack(pady=20)
# Create a button to open a new stock monitoring window
open_button = ttk.Button(
root, text="Monitor Stock", command=lambda: create_stock_window(stock_options[stock_var.get()], stock_var.get())
)
open_button.pack(pady=10)
# Run the Tkinter event loop
root.mainloop()
Here are some ideas for extending this application:
This tutorial demonstrates how to integrate Matplotlib with Tkinter to create dynamic, real-time data visualization applications. With a few modifications, you can adapt this project for various use cases, such as monitoring weather data, cryptocurrency prices, or fitness statistics.