I don’t think there’s one online but here’s an example of what I meant:
import dash
from dash import dcc, html, Input, Output, State
import plotly.graph_objs as go
import pandas as pd
import numpy as np
app = dash.Dash(__name__)
exchanges = ['NYSE', 'NASDAQ', 'LSE', 'TSE']
all_stocks = {}
for exchange in exchanges:
stock_names = [f"{exchange}{i:03d}" for i in range(1, 21)]
dates = pd.date_range(end=pd.Timestamp.today(), periods=365, freq='D')
values = np.random.randint(50, 500, size=(365, 20))
df = pd.DataFrame(values, index=dates, columns=stock_names)
all_stocks[exchange] = df
# App Layout
app.layout = html.Div([
dcc.Dropdown(
id='exchange-dropdown',
options=[{'label': x, 'value': x} for x in exchanges],
value=exchanges[0]
),
dcc.Store(id='figure-store'), # Store the initial figure
dcc.Graph(id='stock-graph')
])
@app.callback(
output=Output('figure-store', 'data'),
inputs=Input('exchange-dropdown', 'value'),
)
def update_graph(exchange):
df = all_stocks[exchange]
fig = go.Figure()
for stock in df.columns:
fig.add_trace(go.Scatter(x=df.index, y=df[stock], mode='lines', name=stock))
fig = fig.to_dict()
for i in range(1, len(fig['data'])):
del fig['data'][i]['x']
return fig
app.clientside_callback(
"""
function(figureDict) {
const figure = {...figureDict}; // Create a copy of the figure data
const x_data=figure.data[0].x;
for (let i = 1; i < figure.data.length; i++) {
figure.data[i].x = x_data;
}
return figure;
}
""",
Output('stock-graph', 'figure'),
Input('figure-store', 'data'),
)
if __name__ == '__main__':
app.run_server(debug=True, port=8055)
This results in a 1/5 of the data transfered compared to a version of the app that repeats the x values (~50 KB vs 250 KB) but after enabling compression it’s only 10% better (13.8 KB vs 15.3 KB). If you’re still interested in this feature feel free to create an issue in Issues · plotly/dash · GitHub
inefficient app:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import pandas as pd
import numpy as np
app = dash.Dash(__name__)
# Generate Fake Stock Data
exchanges = ['NYSE', 'NASDAQ', 'LSE', 'TSE']
all_stocks = {}
for exchange in exchanges:
stock_names = [f"{exchange}{i:03d}" for i in range(1, 21)] # 20 stocks per exchange
dates = pd.date_range(end=pd.Timestamp.today(), periods=365, freq='D')
values = np.random.randint(50, 500, size=(365, 20))
df = pd.DataFrame(values, index=dates, columns=stock_names)
all_stocks[exchange] = df
print(all_stocks.keys())
# App Layout
app.layout = html.Div([
dcc.Dropdown(
id='exchange-dropdown',
options=[{'label': x, 'value': x} for x in exchanges],
value=exchanges[0] # Default to the first exchange
),
dcc.Graph(id='stock-graph')
])
@app.callback(
Output('stock-graph', 'figure'),
Input('exchange-dropdown', 'value')
)
def update_graph(exchange):
df = all_stocks[exchange]
fig = go.Figure()
for stock in df.columns:
fig.add_trace(go.Scatter(x=df.index, y=df[stock], mode='lines', name=stock))
fig.update_layout(
title=f'Top 10 Stock Values on {exchange} (Last Year)',
xaxis_title='Date',
yaxis_title='Value'
)
return fig
if __name__ == '__main__':
app.run_server(debug=True, port=8056)