I have a bullet graph in python-plotly and I want to change which traces are visible using a button that looks to a customdata field.
The whole figure should display 11 bullet-graphs (1 for each of 10 locations and then a grand total) for the time period that the user selects in the button/dropdown. I set things up fine where I make the figure, add each trace (for a single period), and then fig.show()
looks great for that period. To try to accomplish the next steps, I add traces for all periods (I've got 2 YTD for a total of 3 periods, times the 11 graphs each for 33 trace) and set all of them to visible=False
. When I run fig.show()
, they are not visible, as expected.
To try to store my period info, it made the most sense to me (open to suggestions) to use the customdata
on the trace and just set this to the period as I'm making the traces. I've currently got it so each trace has the customdata equal a list with a single item, which is the period.
So, we get to the buttons, here is my code as relates to the button (I pulled a bunch from this SO question:
periods = [1,2]
bullet = reports.main_bullet(df,periods) # my func that builds out all the traces
buttons = []
for period in periods ['All']:
buttons.append(
dict(
method='restyle',
label = period,
visible=True,
args=[{'visible':'customdata'[0]==period}], #help me...
)
)
updatemenu = []
your_menu = dict()
updatemenu.append(your_menu)
updatemenu[0]['buttons'] = buttons
updatemenu[0]['direction'] = 'down'
updatemenu[0]['showactive'] = True
bullet.update_layout(updatemenus=updatemenu)
bullet.show()
In the button args
, I want visible=True
when the period on the trace (which is in customdata[0]
is whatever I've selected on the button. That isn't working...
I'm also open to "you are doing it all wrong, here is the better way to approach the whole thing"
CodePudding user response:
Found something that works, seems reasonable.
So the args[{'visible':...}]
can take a list of booleans and it'll apply them in that order to the traces. So, I just need each button the have the True/False
list that it needs.
indices_for_period = {}
for period in periods ['All']:
indices_for_period[period] = []
for i,data in enumerate(bullet.data):
indices_for_period[data.customdata[0]].append(i)
This creates a dictionary with a key for each period, and the values for each key are the indices for it.
Then I update my visible arg (the the loop) like such:
for period in periods ['All']:
buttons.append(
dict(
method='restyle',
label = period,
visible=True,
args=[
{'visible':[x in indices_for_period[period] for x in range(i 1)]},
],
)
)