I'm writing a small script to plot material data using plotly, I tried to use a dropdown to select which column of my dataframe to display. I can do this by defining the columns one by one but the dataframe will change in size so I wanted to make it flexible.
I've tried a few things and got to this;
for i in df.columns:
fig = go.Figure()
fig.add_trace(go.Scatter(x=df.index, y=df[i]))
fig.update_layout(
updatemenus=[
go.layout.Updatemenu(
buttons=list([
dict(
args=["values", i],
label=i,
method="update"
),
]),
direction="down",
pad={"r": 10, "t": 10},
showactive=True,
x=0.1,
xanchor="left",
y=1.1,
yanchor="top"
),
]
)
fig.update_layout(
annotations=[
go.layout.Annotation(text="Material:", showarrow=False,
x=0, y=1.085, yref="paper", align="left")
]
)
fig.show()
The chart shows the final column of the df, while dropdown only holds the last column header?
My data looks something like this, where i is the index, the chart and dropdown show column 'G';
i A B C D E F G
1 8 2 4 5 4 9 7
2 5 3 7 7 6 7 3
3 7 4 9 3 7 4 6
4 3 9 3 6 3 3 4
5 1 7 6 9 9 1 9
The following suggestion should be exactly what you're asking for. It won't exceed the built-in functionalities to an extreme extent though, meaning that you can already subset your figure by clicking the legend. Anyway, let me know if this is something you can use or if it needs som adjustments.
Plot 1 - State of plot on first execution:
Click the dropdown
in the upper left corner and select, D
for example to get:
Plot 2 - State of plot after selecting D
from dropdown:
Code:
# imports
import plotly.graph_objs as go
import pandas as pd
# data sample
df = pd.DataFrame({'i': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
'A': {0: 8, 1: 5, 2: 7, 3: 3, 4: 1},
'B': {0: 2, 1: 3, 2: 4, 3: 9, 4: 7},
'C': {0: 4, 1: 7, 2: 9, 3: 3, 4: 6},
'D': {0: 5, 1: 7, 2: 3, 3: 6, 4: 9},
'E': {0: 4, 1: 6, 2: 7, 3: 3, 4: 9},
'F': {0: 9, 1: 7, 2: 4, 3: 3, 4: 1},
'G': {0: 7, 1: 3, 2: 6, 3: 4, 4: 9}})
df=df.set_index('i')
# plotly figure setup
fig = go.Figure()
# one trace for each df column
for col in df.columns:
fig.add_trace(go.Scatter(x=df.index, y=df[col].values,
name = col,
mode = 'lines')
)
# one button for each df column
updatemenu= []
buttons=[]
for col in df.columns:
buttons.append(dict(method='restyle',
label=col,
args=[{'y':[df[col].values]}])
)
# some adjustments to the updatemenu
updatemenu=[]
your_menu=dict()
updatemenu.append(your_menu)
updatemenu[0]['buttons']=buttons
updatemenu[0]['direction']='down'
updatemenu[0]['showactive']=True
# update layout and show figure
fig.update_layout(updatemenus=updatemenu)
fig.show()