Advanced Dropdown Menus with Plotly

Hi,

I am trying to create an interactive plot in Python with Plotly that has two dropdown menus.

The first one would select between different datasets, and the second one would select a certain variable from the selected dataset to display.

I stumbled across these two posts:
https://www.kaggle.com/jrmistry/plotly-how-to-change-plot-data-using-dropdowns

The first Kaggle article has a script that takes an input dataframe with an interactive dropdown menu that can chose which variable to display.

The second stackoverflow has a script that allows you to alter the datasets used to create the different plots.

I would like to combine both, and I have been pondering how to make it work all day…

I found this post about using Dash:

Which I suppose has the interactive component between the different dropdown menus down, but I am wondering if there is a way to recreate the dcc.Dropdown feature in Plotly as to avoid building it in Dash.

I have tried toying with the buttons feature in Plotly but too my understanding the only args I can pass to it are ones that are used in the β€œinternal” plotting functions of go?

Ideally I would pass a dictionary of dataframes, select a dataframe, select a variable and voila a desired plot.

Best regards

Hi @Waterboi,

This is the plotly.py version of the interactive plot you are interested in:

import plotly.graph_objs as go
import pandas as pd

df1 = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/solar.csv')
df2 = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')    

# Rename the lists of columns
cols1 = df1.columns
cols2 = df2.columns

fig = go.Figure()
fig.add_scatter(x=df1[cols1[0]], y=df1[cols1[1]], mode='lines')
fig.add_scatter(x=df2[cols2[0]], y=df2[cols2[1]], mode='lines', visible=False);

#The trace restyling  to be performed at an option selection in the first/second dropdown menu
# is defined within  buttons1/buttons2 below:

buttons1 = [dict(method = "restyle",
                 args = [{'x': [df1[cols1[0]], 'undefined'],
                          'y': [df1[cols1[k]], 'undefined'],
                          'visible':[True, False]}], 
                 label = cols1[k])   for k in range(1, len(cols1))]  

buttons2 = [dict(method = "restyle",
                 args = [{'x': ['undefined', df2[cols2[0]]],
                          'y': ['undefined', df2[cols2[k]]],
                          'visible':[False, True]}],
                 label = cols2[k])   for k in range(1, 7)]


fig.update_layout(title_text='Plot title',
                  title_x=0.4,
                  width=850,
                  height=450,
                 
                  updatemenus=[dict(active=0,
                                    buttons=buttons1,
                                    x=1.15,
                                    y=1,
                                    xanchor='left',
                                    yanchor='top'),
                              
                               dict(buttons=buttons2,
                                    x=1.15,
                                    y=0.85,
                                    xanchor='left',
                                    yanchor='top')
                              ]); 

#Add annotations for the two dropdown menus:

fig.add_annotation(
            x=1.065,
            y=1,
            xref='paper',
            yref='paper',
            showarrow=False,
            xanchor='left',
            text="df1<br>State")
fig.add_annotation(
            x=1.065,
            y=0.85,
            showarrow=False,
            xref='paper',
            yref='paper',
            xanchor='left',
            #yanchor='top',
            text="df2<br>Date");

The corresponding plot: https://chart-studio.plotly.com/~empet/15696/#/.
Details:
The default Figure consists in two traces: the trace 0 is a scatter plot with x-values in the df1-column of index 0,
and y-values in the df1-column 1, while trace 1 has the df2-column 0, as x-values, and column 1 in the same dataframe, as y-values.

Two each dataframe is associated a dropdown menu: the first one with n options, n=len(df1.columns)-1, and the second one with 6 options. Selecting the kth option of the first dropdown menu, the trace fig.data[0] is updated by the pair of columns, (0, k), in the dataframe, df1, and similarly when selecting an option in the second dropdown menu. More precisely, the trace fig.data[0]/fig.data[1] is restyled according to settings in the args[0] dict of the corresponding item in the list buttons1/buttons2 . (More on trace restyling here https://chart-studio.plotly.com/~empet/15607)

The β€˜undefined’ in the position 1 or 0 of the β€˜x’, β€˜y’- lists means that the current state of the trace fig.data[1] or fig.data[0] is unchanged.

Thank you, good sir!