I have a line plot with a range slider and a dropdown to dynamically update the plot and this works very nicely, however, I would also like to remake this with a checklist instead of a dropdown, sounds simple but I’m struggling to display the data so it looks the same as the dropdown, which I love.
So far this is what I’ve done for my range slider dropdown and it works to my satisfaction.
import everything I need
path = r'C:\Users\2022.csv'
df = pd.read_csv(path)
df_zones = pd.DataFrame({
'DK1': df['DK1'],
'DK2': df['DK2'],
'FI': df['FI'],
'NO1': df['NO1'],
'NO2': df['NO2'],
'NO3': df['NO3'],
'NO4': df['NO4'],
'NO5': df['NO5'],
'SE1': df['SE1'],
'SE2': df['SE2'],
'SE3': df['SE3'],
'SE4': df['SE4'],
})
fig = go.Figure(layout=go.Layout(
title=go.layout.Title(text="Error (Results - Forecast)")
))
for column in df.columns.to_list():
fig.add_trace(
go.Scatter(
x = df.index,
y = df[column],
name = column
)
)
fig.update_layout(
updatemenus=[go.layout.Updatemenu(
active=0,
buttons=list(
[dict(label = 'All zones',
method = 'update',
args = [{'visible': [True, True, True, True,True, True,True, True,True, True,True, True]},
{'title': 'All',
'showlegend':True}]),
dict(label = 'DK',
method = 'update',
args = [{'visible': [True, True, False, False, False, False, False, False, False, False, False, False]}, # the index of True aligns with the indices of plot traces
{'title': 'Denmark',
'showlegend':True}]
# Here I've omitted all the other buttons I use for economy.
)
])
fig.update_xaxes(rangeslider_visible=True) #ranges slider
fig.show()
Next is what I’ve attempted with the checklist and it displays, terribly. The graph is squeezed into the top 50% of the page and the buttons don’t work yet. Each selection of a checklist button should update the graph and display the new data. I think I’ve misunderstood something in the two approaches but these two methods produce vastly different results and I don’t understand why.
I’m aware I need to add some functionality to update the graph with the ‘y’ component but before I do that I want to be clear on what is the best method and why.
When should I use a callback for a graph update? and is it better than the update_layout method? What is the difference here and what would make the most sense for me to do to replicate my first attempt?
DK = df.columns[1:3]
FI = df.columns[3:4]
NO = df.columns[4:9]
SE = df.columns[9:13]
#%%
zone_dict = {'DK':'Denmark', 'FI':'Finland', 'NO':'Norway', 'SE':'Sweden' }
ID = 'DK'
zone_ID = zone_dict[ID]
# Create the line graph
line_graph = px.line(
# Set the appropriate DataFrame and title
data_frame= df, title='Flow for '+zone_ID,
# Set the x and y arguments
x='DateTimeUtc', y= ['DK1','FI'])
# Create the Dash app
app = dash.Dash(__name__)
# Set up the layout with a single graph, inside a children argument so we can add multiple elements
# ID's also important for callbacks
app.layout = html.Div(children = [html.H1('Error'),
dcc.Checklist(id='my-checklist', options=[{'label': col, 'value': col} for col in df.columns],
value=df.columns.tolist(),
labelStyle={'display': 'inline-block'}
),
dcc.Graph(id='my-line-graph', figure=line_graph)
])
line_graph.update_xaxes(rangeslider_visible=True)
# Set the app to run in development mode
if __name__ == '__main__':
app.run_server(debug=False)
Head of dataframe
NDFrame.head of DK1 DK2 ... SE3 SE4
DateTimeUtc ...
2022-01-01 00:00:00 1691.712 463.951 ... -112.99925 93.56625
2022-01-01 01:00:00 1244.341 318.301 ... 68.27500 345.15800
2022-01-01 02:00:00 927.078 175.081 ... 308.46300 648.40400
2022-01-01 03:00:00 612.140 43.902 ... 450.57400 935.90600
2022-01-01 04:00:00 934.235 98.501 ... 559.55400 794.34800
... ... ... ... ...
2022-12-31 20:00:00 2217.632 -54.234 ... 581.45780 577.19120
2022-12-31 21:00:00 2751.985 -105.601 ... 605.69085 521.62715
2022-12-31 22:00:00 2972.932 -100.368 ... 725.38635 485.12365
Thanks for any input.