The fast food industry represents one of the most dynamic sectors in the stock market, with companies ranging from global giants like McDonald's to innovative newcomers like Luckin Coffee. In this project, you'll create an interactive line chart to visualize historical stock prices for 10 major fast-food companies. Building interactive dashboards is a critical skill in modern business, as these tools help analysts, portfolio managers, and executives make informed, data-driven decisions.
Dataset Summary
Your primary dataset, companies.csv
, contains historical stock market data from Yahoo Finance. This dataset captures daily trading activity from major players across the fast food sector. It includes stock data from these industry leaders:
Ticker | Company | Description |
---|---|---|
BRK-A | Berkshire Hathaway Inc. | Financial conglomerate with major fast food investments |
DNUT | Krispy Kreme, Inc. | Specialty donut and coffee retailer |
DPZ | Domino's Pizza, Inc. | Global pizza delivery leader |
LKNCY | Luckin Coffee Inc. | Chinese coffee chain competitor |
MCD | McDonald's Corporation | World's largest fast food restaurant chain |
PZZA | Papa John's International | Pizza delivery and takeout specialist |
QSR | Restaurant Brands International | Parent of Burger King, Tim Hortons, and Popeyes |
SBUX | Starbucks Corporation | Global coffeehouse chain |
WEN | The Wendy's Company | Premium burger restaurant chain |
YUM | Yum! Brands, Inc. | Parent of KFC, Taco Bell, and Pizza Hut |
Note: A ticker is a unique stock symbol used to identify companies on exchanges (e.g., "MCD" for McDonald's, "SBUX" for Starbucks).
Data Structure
companies.csv
Column | Description |
---|---|
date | Trading date |
open | Opening price for the trading session |
high | Highest price during the day |
low | Lowest price during the day |
close | Closing price at market close |
adj_close | Price adjusted for dividends and stock splits |
volume | Number of shares traded |
company_ticker | Company stock symbol identifier |
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
# Read the CSV file
companies = pd.read_csv('companies.csv')
# Ensure 'date' is in datetime format
companies['date'] = pd.to_datetime(companies['date'])
companies.head()
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
# Read the CSV file
companies = pd.read_csv('companies.csv')
# Ensure 'date' is in datetime format
companies['date'] = pd.to_datetime(companies['date'])
# --- Set up the list of company tickers, column labels, and default selections for the plot ---
tickers = ["BRK-A", "DNUT", "DPZ", "LKNCY", "MCD",
"PZZA", "QSR", "SBUX", "WEN", "YUM"]
# OPTIONAL: friendly labels for cleaner dropdown text
col_map = {
"open": "Open", "high": "High", "low": "Low",
"close": "Close", "adj_close": "Adj Close", "volume": "Volume"
}
default_tkr = "DPZ"
default_col = "close"
# --- Build one trace per company for the default column ---
fig = go.Figure()
for t in tickers:
sub = companies[companies["company_ticker"] == t]
trace = px.line(sub, x="date", y=default_col).data[0]
trace.visible = (t == default_tkr) # OPTIONAL: default company only → cleaner first view
fig.add_trace(trace)
# --- Dropdown for company selection; updates visible trace only ---
company_buttons = []
for i, t in enumerate(tickers):
vis = [False] * len(tickers); vis[i] = True
company_buttons.append({
'label': t,
'method': "update",
'args': [
{'visible': vis},
{'title': f"{t} – {col_map[default_col]}"} # OPTIONAL: a dynamic title
]
})
# --- Dropdown for column selection; updates y-data for all traces (not shown in course) ---
column_buttons = []
for c_key, c_lbl in col_map.items():
y_lists = [companies[companies["company_ticker"] == tt][c_key]
for tt in tickers]
column_buttons.append({
'label': c_lbl,
'method': "update",
'args': [
{'y': y_lists}, # Updates y-data for each trace; this pattern not shown in slides
{'title': f"{default_tkr} – {c_lbl}"}
]
})
# --- Range-selector buttons for time filtering ---
range_buttons = [
{'count': 1, 'step': "month", 'stepmode': "backward", 'label': "1M"},
{'count': 6, 'step': "month", 'stepmode': "backward", 'label': "6M"},
{'count': 1, 'step': "year", 'stepmode': "backward", 'label': "1Y"},
{'count': 3, 'step': "year", 'stepmode': "backward", 'label': "3Y"}
]
# --- Update layout with two dropdowns and time buttons ---
fig.update_layout({
'title': f"{default_tkr} – {col_map[default_col]}",
'xaxis': {
'rangeselector': {'buttons': range_buttons},
'rangeslider': {'visible': False},
'type': 'date'
},
'updatemenus': [
{'type': "dropdown", 'direction': 'down',
'x': 1.12, 'y': 1.00, 'showactive': True,
'buttons': company_buttons,
'active': tickers.index(default_tkr)},
{'type': "dropdown", 'direction': 'down',
'x': 1.12, 'y': 0.6, 'showactive': True,
'buttons': column_buttons,
'active': list(col_map).index(default_col)}
],
'hovermode': "x unified" # OPTIONAL: unified tooltip → less clutter
})
fig.show()