Hi @friendlypanda,
I see,
This lines below maybe a hack of modified code, but I hope this is help you solve your issues.
I try to create traces using Plotly express, I add 2 additional columns of dataframe, so the df have 5 columns ['test1','test2','test3','test4','test5']
.
df = pd.DataFrame({'test1': [1, 2, 3, 4], 'test2':[4, 5, 4, 7], 'test3':['a','b','c', 'd'],'test4':['E','F','G', 'H'],'test5':['W','X','Y', 'Z']})
The dropdown menu options will be [‘test3’,‘test4’,‘test5’], so the color will be using this 3 columns.
fig1 = px.scatter(df,x='test1', y="test2", color='test3', width=600, height=400, hover_data=['test1','test2'])
fig2 = px.scatter(df,x='test1', y="test2", color='test4', width=600, height=400, hover_data=['test1','test2'])
fig3 = px.scatter(df,x='test1', y="test2", color='test5', width=600, height=400, hover_data=['test1','test2'])
Creating traces by using Plotly Express will keep the discreate color feature on the traces, so the it will show the categorical color instead continuous colorbar. ( And actually you can use Plotly graph objects as well but you need create all traces manually)
Get all traces from all plotly express figures by using fig1.data
, fig2.data
,fig3.data
into new Figure objects fig
.
# Get the Sactter traces and add into new Figure object `fig`
fig = go.Figure()
fig.add_traces(fig1.data) # fig1.data is tuple of traces
fig.add_traces(fig2.data)
fig.add_traces(fig3.data)
For initial view set the visible traces just for test3
fig.for_each_trace(
lambda trace: trace.update(visible=False) if trace.name not in df.test3.unique().tolist() else ()
)
To update legend by selected dropdown options, you need to add this line to args
attribute.
{"legend": {"title": {"text": col}}} # Update the legend of discrete color
Finally set test3
as initial legend title
fig.update_layout(
title="Test data",
legend_title_text="text3", # initial color legend
..
And here is the complete code.
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
df = pd.DataFrame({'test1': [1, 2, 3, 4], 'test2':[4, 5, 4, 7], 'test3':['a','b','c', 'd'],'test4':['E','F','G', 'H'],'test5':['W','X','Y', 'Z']})
## Create 3 figures with different color based on 3 column.
fig1 = px.scatter(df,x='test1', y="test2", color='test3', width=600, height=400, hover_data=['test1','test2'])
fig2 = px.scatter(df,x='test1', y="test2", color='test4', width=600, height=400, hover_data=['test1','test2'])
fig3 = px.scatter(df,x='test1', y="test2", color='test5', width=600, height=400, hover_data=['test1','test2'])
# Get the Sactter traces and add into new Figure object `fig`
print(fig1.data)
fig = go.Figure()
fig.add_traces(fig1.data) # fig1.data is tuple of traces
fig.add_traces(fig2.data)
fig.add_traces(fig3.data)
# For initial view set the visible traces just for `test3`
fig.for_each_trace(
lambda trace: trace.update(visible=False) if trace.name not in df.test3.unique().tolist() else ()
)
buttonlist = []
## This lines are modified version using method update
for col in ["test3","test4","test5"]:
buttonlist.append(
dict(
# the idea is to show the trace of selected dropdown and hide the other traces.
args=[{"visible": [col=='test3']*len(df.test3.unique()) \
+ [col=='test4']*len(df.test4.unique()) \
+ [col=='test5']*len(df.test5.unique())
},
{"legend": {"title": {"text": col}}} # Update the legend of discrete color
],
label=str(col),
method='update'
)
)
fig.update_layout(
title="Test data",
legend_title_text="text3", # initial color legend
updatemenus=[
go.layout.Updatemenu(
buttons=buttonlist,
direction="down",
pad={"r": 5, "t": 5},
showactive=False,
x=0.1,
xanchor="left",
y=1.1,
yanchor="top"
),
],
autosize=True
)
fig.show()