Hello,
I am having difficulties updating yaxis_categoryarray
via the 'update'
method of a Plotly dropdown. Here is a minimum problematic example to show the problem.
First, the setup:
# -*- coding: utf-8 -*-
import random
import pandas as pd
import plotly.graph_objects as go
ngroups = 3
ncategories = 20
ncategories = min(65+ncategories,91)-65
categories = list(map(chr, range(65, 65+ncategories)))
groups = list(map(chr, range(65, 65+ngroups)))
df = pd.DataFrame(categories, columns=['Cat'])
df['data'] = [random.choice(['No','Yes']) for i in range(ncategories)]
df['x'] = 1
df['groups'] = ['Group ' + random.choice(groups) for i in range(ncategories)]
Here, categories will go along the yaxis and are stored in the column Cat
in the dataframe. The data is either 'Yes'
or 'No'
and all the data is at x=1
. The categories are then distributed amongst ngroup
groups.
I create multiple scatter plots, one for 'Yes'
, one for 'No'
for each group in groups
data = []
groups = sorted(df['groups'].unique())
for group in groups:
mask = df[df['groups'] == group]
dfno = mask[mask['data'] == 'No']
dfyes = mask[mask['data'] == 'Yes']
data.append(
go.Scatter(
name='Yes',
mode='markers',
legendgroup='Yes',
marker=dict(size=16),
visible = True if group == groups[0] else False,
x=dfyes['x'] if len(dfyes.index) > 0 else [None],
y=dfyes['Cat'] if len(dfyes.index) > 0 else [None],))
data.append(
go.Scatter(
name='No',
legendgroup='No',
mode='markers',
marker=dict(size=16),
visible = True if group == groups[0] else False,
x=dfno['x'] if len(dfno.index) > 0 else [None],
y=dfno['Cat'] if len(dfno.index) > 0 else [None],))
I then create the figure
fig = go.Figure(
data=data,
layout = dict(
showlegend=True,
yaxis=dict(
type='category',
categoryarray=sorted(list(set(df[df['groups']==groups[0]]['Cat'].tolist())))[::-1],
categoryorder='array')))
Now to create the dropdown, which will both make the apropiate traces visible and update yaxis_categoryarray
.
index=0
buttons=[]
for group in groups:
visible = [False] * len(groups) * 2
visible[index:index+1] = [True, True]
index += 2
group_categories = sorted(list(set(df[df['groups']==group]['Cat'].tolist())))[::-1]
print(group)
print(group_categories)
buttons.append(
dict(
label=group,
method='update',
args = [{'visible': visible},
{'yaxis_categoryarray': group_categories}]))
fig.update_layout(
updatemenus=[
dict(
buttons=buttons,
bgcolor="white",
x=1,
xanchor="right",
y=1.04,
yanchor="top",)])
fig.show()
Unfortunately, the problem is encountered here and categoryarray
is not updated. Said another way, the yaxis
is correct for the first button selection but not the other ones. In fact, for the other ones, the points are sorted by trace.
If instead I use categoryorder="category descending"
and drop the categoryarray
argument, the resulting figure is completly gone (no axis, no traces, no dropdown, and no error).
Is there an error in the code above? A missing option perhaps? Or is this a bug?