Search code examples
pythonpandasdrop-down-menuplotly

Use plotly to plot multiple pandas column with a dropdown menu to select column


I have a pandas dataframe for which I am trying to a plot bar graph using Plotly with a dropdown menu to select by the stock name column, referring this answer.

But I am unsure how do I add multiple columns to the updatemenus as the names of the columns could vary.

import plotly.graph_objects as go
# plotly setup
fig = go.Figure()

# Add traces, starting from First Column. Each column is a stock data.
for mycolumn in df.columns[1:]:
    fig.add_traces( go.Scatter(x=list(df.Quarters), y=list(df[mycolumn])) )

updatemenus = None

for mycolumn in df.columns[1:]:
    # construct menus
    updatemenus = [{'buttons': 
                    [{'method': 'update',
                      'label' : column, # what?
                      'args'  : [{'y': [values_1, values_1b]},] # what?
                     }
                    'direction': 'down',
                    'showactive': True,}
                  ]

# update layout with buttons, and show the figure
fig.update_layout(updatemenus=updatemenus)
fig.show()

The dataframe for ref:

Quarters 526433 AARTIIND DEEPAKNTR GREENPANEL METROBRAND MOLDTECH MUFTI MUTHOOTFIN YASHO ZENTEC
Mar-21 4.6 1.69
Jun-21 2.99 4.55 22.19 2.43 1.16 24.37 10.01 -0.14
Sep-21 3.77 4.14 18.65 5.47 1.89 1.3 24.97 12.44 0
Dec-21 4.3 20.01 17.78 5.14 3.69 0.59 25.91 12.71 -0.02
Mar-22 1.54 5.34 19.59 6.57 2.49 1.67 24.84 11.69 0.42
Jun-22 3.35 3.75 17.2 6.33 3.8 1.1 20.41 16.99 0.94
Sep-22 2.84 3.42 12.79 5.91 2.72 2.43 80.9 22.22 19.61 0.71
Dec-22 2.25 3.77 15.33 3.06 4.22 3.26 60.25 23.11 9.18 1.19
Mar-23 0.25 4.11 17.15 5.62 2.44 3.58 67.43 24.25 13.76 2.54
Jun-23 0.36 1.93 10.99 3.04 3.91 2.21 1.33 25.46 12.97 5.6
Sep-23 -1.59 2.51 15.04 3.34 2.92 2.86 4.35 26.39 10.23 1.82
Dec-23 -0.19 3.42 14.81 2.82 3.52 2.47 2.42 27.49 11.88 3.64
Mar-24 -2.59 3.64 18.61 2.43 6.05 2.26 1.1 28.37 15.74 4.16
Jun-24 2.83 3.78 14.85 3.4 1.81 1.51 28.99 -2.16 9.14

Solution

  • As mentioned in the linked post:

    'y' = [values_1] where values_1 is a list in itself.

    So, we need 'y': [df[col]] for each col in df.iloc[:, 1:]. For the label value use col itself. Also make sure only to add a trace for your first column, as this will give us the result for the first selection.

    import plotly.graph_objects as go
    
    fig = go.Figure()
    
    # add trace only for first stock
    x = df['Quarters']
    y = df['526433']
    fig.add_traces(go.Scatter(x=x, y=y))
    
    # create `list` with a `dict` for each column
    buttons = [{'method': 'update', 'label': col, 'args': [{'y': [df[col]]}]} 
               for col in df.iloc[:, 1:]]
    
    # add menus
    updatemenus = [{'buttons': buttons,
                    'direction': 'down',
                    'showactive': True,}]
    
    # update layout with buttons, and show the figure
    fig.update_layout(updatemenus=updatemenus)
    fig.show()
    

    Output:

    output with menu

    Data used

    import pandas as pd
    import numpy as np
    
    data = {'Quarters': {0: 'Mar-21', 1: 'Jun-21', 2: 'Sep-21', 3: 'Dec-21', 4: 'Mar-22', 
                         5: 'Jun-22', 6: 'Sep-22', 7: 'Dec-22', 8: 'Mar-23', 9: 'Jun-23', 
                         10: 'Sep-23', 11: 'Dec-23', 12: 'Mar-24', 13: 'Jun-24'}, 
            '526433': {0: np.nan, 1: 2.99, 2: 3.77, 3: 4.3, 4: 1.54, 5: 3.35, 6: 2.84, 
                       7: 2.25, 8: 0.25, 9: 0.36, 10: -1.59, 11: -0.19, 12: -2.59, 13: 2.83}, 
            'AARTIIND': {0: np.nan, 1: 4.55, 2: 4.14, 3: 20.01, 4: 5.34, 5: 3.75, 6: 3.42,
                         7: 3.77, 8: 4.11, 9: 1.93, 10: 2.51, 11: 3.42, 12: 3.64, 13: 3.78}, 
            'METROBRAND': {0: 1.69, 1: np.nan, 2: 1.89, 3: 3.69, 4: 2.49, 5: 3.8, 6: 2.72, 
                           7: 4.22, 8: 2.44, 9: 3.91, 10: 2.92, 11: 3.52, 12: 6.05, 13: 3.4}
           }
    df = pd.DataFrame(data)