Plotly: How to create a dropdown button that groups lines in a line graph?

Viewed 1078

I made a line chart with way too many lines to neatly display and I need to be able to select a grouping variable (Province) and have it just display the lines in that province (I have a Province column in the data that says what Province it belongs to). For example, I would click "Ontario" in the dropdown and just the lines corresponding to Toronto and Ottawa etc would show up. What am I doing wrong?

enter image description here

import plotly.express as px
import plotly.offline as pyo
import pandas as pd
import plotly.graph_objects as go

df = pd.read_csv('....csv')


fig_opend = px.line(data_frame = df, x='Round', y='Excess Demand For Plot', title= 'Canada', color='Product' ,
                    hover_name='Service Area Name', hover_data=['Product Number', 'Excess Demand', '(Initial) Supply', 'Aggregate Demand', 'Round'])



fig_opend.update_yaxes(title = 'Excess Demand')


fig_opend.update_layout(margin={"r":20,"t":27,"l":10,"b":10}, xaxis={'tickformat':',d'})


updatemenus = [dict(buttons_open=list([dict(method='update', args=[{'y':[df.loc[df_opend['Areas'] == 'West']]}],),]),direction="down",showactive=True)]

fig_opend.update_layout(updatemenus=updatemenus)
1 Answers

All you have to do is:

1. Build a figure for all series with px.line(df, x=df.index, y = df.columns)

2. Map your lines / traces / series to groups using something like:

maps = {'group 1': ['GOOG', 'AAPL', 'AMZN', 'FB'],
           'group 2':['NFLX', 'MSFT']}

(I'm using the px.data.stocks() dataset since you haven't provided one)

3. Set up a list of lists of which traces will be visible for which groups in your figure with:

[[True, True, True, True, False, False],
 [False, False, False, False, True, True]]

(And don't worry, that will be handled dynamically with a nested For Loop).

4. Use those lists to trigger the visibilites through the push of a button in:

button =  dict(label=g,
               method = 'restyle',
                args = ['visible',visList[i]])

The complete code snippet below will produce the following figure:

Plot 1:

enter image description here

And if you select for example Group 2 then you'll get:

Plot 2:

enter image description here

Take it for a spin and see if this is what you were looking for!

# imports
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

# data
df = px.data.stocks().set_index('date')
maps = {'group 1': ['GOOG', 'AAPL', 'AMZN', 'FB'],
           'group 2':['NFLX', 'MSFT']}

# plotly figure
fig = px.line(df, x=df.index, y = df.columns) 

# groups and trace visibilities
group = []
vis = []
visList = []
for m in maps.keys():
    for col in df.columns:
        if col in maps[m]:
            vis.append(True)
        else:
            vis.append(False)
    group.append(m)
    visList.append(vis)
    vis = []

# buttons for each group
buttons = []
for i, g in enumerate(group):
    button =  dict(label=g,
                   method = 'restyle',
                    args = ['visible',visList[i]])
    buttons.append(button)

buttons = [{'label': 'all',
                 'method': 'restyle',
                 'args': ['visible', [True, True, True, True, True, True]]}] + buttons

                     

# update layout with buttons                       
fig.update_layout(
    updatemenus=[
        dict(
        type="dropdown",
        direction="down",
        buttons = buttons)
    ],
)
# buttons
fig.show()
Related