If you just want to adapt the ranges, I would use partial updates and Patch
. That’s way faster than creating the figure and updating it.
from dash import Patch
@callback(
Output(component_id='generated-graph', component_property='figure'),
Input(component_id='generated-graph', component_property='figure'),
Input(component_id='date-picker', component_property='start_date'),
Input(component_id='date-picker', component_property='end_date'),
prevent_initial_call=True
)
def month_filtering(fig, start, end):
patched = Patch()
patched["layout"]["xaxis"] = {"range": [start, end]}
patched["layout"]["title"] = {"text": f'Filtered Data from {start} to {end}'}
return patched
As you can see, you do not need the figure as input.
MRE:
import dash
from dash import dcc, html, Input, Output, callback, Patch
import plotly.graph_objects as go
import pandas as pd
import datetime
import random
# Initialize the Dash app
app = dash.Dash(__name__)
# Sample data for demonstration
dates = pd.date_range('2023-01-01', '2024-12-31', freq='D')
sample_data = pd.DataFrame({
'date': dates,
'value': [random.random() for _ in range(len(dates))]
})
# Create initial figure
initial_fig = go.Figure()
initial_fig.add_trace(go.Scatter(
x=sample_data['date'],
y=sample_data['value'],
mode='lines',
name='Sample Data'
))
initial_fig.update_layout(title='Sample Time Series Data')
# App layout
app.layout = html.Div([
html.H1("Dash App with Date Filtering"),
dcc.DatePickerRange(
id='date-picker',
start_date=datetime.date(2023, 1, 1),
end_date=datetime.date(2024, 12, 31),
display_format='YYYY-MM-DD'
),
dcc.Graph(
id='generated-graph',
figure=initial_fig
)
])
# Your callback function (with corrections)
@callback(
Output(component_id='generated-graph', component_property='figure'),
Input(component_id='date-picker', component_property='start_date'),
Input(component_id='date-picker', component_property='end_date'),
prevent_initial_call=True
)
def month_filtering(start, end):
patched = Patch()
patched["layout"]["xaxis"] = {"range": [start, end]}
patched["layout"]["title"] = {"text": f'Filtered Data from {start} to {end}'}
return patched
# Run the app
if __name__ == '__main__':
app.run(debug=True)