Search code examples
plotlyplotly-python

plotly.express.bar assign color to marks for each button selection


Question: how do I assign color to marks (bars) for each button selection. What needs to be added to updatemenus?

The following code generates the charts properly if I comment out color = 'GEO', but I want each of the bars to be a different color.

import pandas as pd
import plotly
import plotly.express as px
import io
 
df = pd.read_csv(io.StringIO(""" num CAT GEO value1
   1     A   Ontario  40
   2     A   Quebec   20
   3     A   Manitoba 30
   4     A   Alberta  60
   1     B   Ontario  35
   2     B   Quebec   10
   3     B   Manitoba 20
   4     B   Alberta  10"""), sep="\s+")
 
dfA = df[df['CAT']=='A']
dfB = df[df['CAT']=='B']
 
fig = px.bar(dfA, 
             x = 'GEO', 
             y = 'value1',
             color = 'GEO',
             height = 400, 
             width = 700)
 
updatemenus = [{
                'buttons': [{'method': 'update',
                             'label': 'Select: A or B',
                             'args': [{'y': [dfA['value1']],
                                       'visible': True},
                                      {'title':'A'},
                                      ],
                             'args2': [{'y': [dfB['value1']],
                                       'visible': True},
                                       {'title':'B'},
                                      ]
                              },
                            ],
                'type':'buttons',
                'direction': 'down',
                'showactive': True,}]
 
fig.update_layout(updatemenus = updatemenus)
fig.show()

Current Output: enter image description here

Desired Output: enter image description here


Solution

  • You may be able to handle this in express, but use a graph object to create a graph, once with the two categories of data. Hide a category. The drop-down functionality gives the display a list of display hides. I have four categories for this graph data, so I will list the display hides.

    import plotly.graph_objects as go
    
    fig = go.Figure()
    
    for c in df['CAT'].unique():
        dff = df.query('CAT == @c')
        for row in dff.itertuples():
            fig.add_trace(go.Bar(x=[row.GEO], y=[row.value1], name=row.GEO, visible=True))
    
    # category(CAT='B') hidden
    for i in range(4): 
        fig.data[i+4].visible=False
    
    updatemenus = [{
                    'buttons': [{'method': 'update',
                                 'label': 'Select: A',
                                 'args': [{'visible': [True,True,True,True,False,False,False,False]},
                                          {'title':'A'}]},
                                {'method': 'update',
                                 'label': 'Select: B',
                                 'args': [{'visible': [False,False,False,False,True,True,True,True]},
                                          {'title':'B'}]}
                               ],
        'type':'buttons',
        'direction': 'down',
        'showactive': True
        }]
     
    fig.update_layout(updatemenus = updatemenus)
    
    fig.show()
    

    enter image description here enter image description here