1

I have grouped data with more than 2 groups. I then plot it with a grouped barchart using plotly for a specific set of 2 groups. How can I create 2 dropdown menus that select which group to be plotted as trace1 and which group as trace2?

The example below uses hardcoded groups 1 for trace1 and group 2 for trace2. I would like to control these with the dropdown menus.

import pandas as pd
import plotly as py
import plotly.graph_objs as go

d = {'x': ['a','b','c','a','b','c','a','b','c'], 'y': [1,2,3,10,20,30,100,200,300], 'group': [1,1,1,2,2,2,3,3,3]}
df = pd.DataFrame(data=d)


trace1 = go.Bar(
    x=df['x'],
    y=df[df['group']==1].y,
    name='trace1'
)
trace2 = go.Bar(
    x=df['x'],
    y=df[df['group']==2].y,
    name='trace2'
)
data = [trace1, trace2]
layout = go.Layout(
    barmode='group'
)

fig = go.Figure(data=data, layout=layout)
py.offline.plot(fig, filename='grouped-bar')

Plot:

enter image description here

2
  • What have you tried so far? This seems like a good place to start: plot.ly/python/dropdowns Commented Mar 18, 2019 at 17:12
  • I have tried the examples but they show more complex cases with restyling or changing the plot type. It is difficult for me to extract a simpler functionality of just selecting which data to be plotted. Commented Mar 18, 2019 at 17:16

1 Answer 1

3

The following suggestion should let you do exactly what you're looking for. Just select the source of the traces using the two dropdown menus:

Plot 1 - Selection is group 1 vs group 1:

enter image description here

Plot 2 - Selection is group 2 vs group 3:

enter image description here

Code:

# Imports
import plotly.graph_objs as go
import pandas as pd
import numpy as np

# data
d = {'x': ['a','b','c','a','b','c','a','b','c'], 'y': [1,2,3,10,20,30,100,200,300], 'group': [1,1,1,2,2,2,3,3,3]}
df = pd.DataFrame(data=d)

# split df by groups and organize them in a dict
groups = df['group'].unique().tolist()
dfs={}
for g in groups:
    dfs[str(g)]=df[df['group']==g]

# get column names from first dataframe in the dict
#colNames = list(dfs[list(dfs.keys())[0]].columns)
#colNames=colNames[:2]


# one trace for each column per dataframe
fig=go.Figure()

# set up the first trace
fig.add_trace(go.Bar(x=dfs['1']['x'],
                             y=dfs['1']['y'],
                             visible=True)
             )
# set up the second trace
fig.add_trace(go.Bar(x=dfs['1']['x'],
                             y=dfs['1']['y'],)
             )

#f=fig.to_dict()

# plotly start
# buttons for menu 1, names
updatemenu=[]
buttons=[]

# button with one option for each dataframe
for df in dfs.keys():
    #print(b, df)
    buttons.append(dict(method='restyle',
                        label=df,
                        visible=True,
                        args=[{'y':[dfs[str(df)]['y'].values],
                               'type':'bar'}, [0]],
                        )
                  )

# another button with one option for each dataframe
buttons2=[]
for df in dfs.keys():
    buttons2.append(dict(method='restyle',
                        label=df,
                        visible=True,
                        args=[{'y':[dfs[str(df)]['y'].values],
                               'type':'bar'}, [1]],
                        )
                  )

# some adjustments to the updatemenus
updatemenu=[]
your_menu=dict()
updatemenu.append(your_menu)
your_menu2=dict()
updatemenu.append(your_menu2)
#updatemenu[1]
updatemenu[0]['buttons']=buttons
updatemenu[0]['direction']='down'
updatemenu[0]['showactive']=True
updatemenu[1]['buttons']=buttons2
updatemenu[1]['y']=0.5

# add dropdown menus to the figure
fig.update_layout(showlegend=False, updatemenus=updatemenu)

# add notations to the dropdown menus
fig.update_layout(
    annotations=[
        go.layout.Annotation(text="<b>group/<br>trace:</b>",
                             x=-0.15, xref="paper",
                             y=1.15, yref="paper",
                             align="left", showarrow=False),
        go.layout.Annotation(text="<b>group/<br>trace:</b>",
                             x=-0.15, xref="paper", y=0.6,
                             yref="paper", showarrow=False),
                  ]
)

fig.show()
Sign up to request clarification or add additional context in comments.

1 Comment

@Konstantin Thank you for accepting my suggestion. This answer would not have been possible without the effort from user nicolaskruchten on the answer to the question: How to update one specific trace using updatemenus? I'd also suggest you take a look at How do the buttons for the update menus really work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.