1

Say I have a function that returns a chart. I want a user to be able to select from a drop down menu and their selections become the inputs to the function. Here is an MRE, but the actual charts and data I'm using are much more complicated so I don't want to use shortcuts or change which data is passed into the chart.

I've already read this documentation. https://plotly.com/python/dropdowns/

Here is the MRE:

import plotly.express as px

data_canada = px.data.gapminder().query("country == 'Canada'")

def charts(input):
    if input == 'A':
        fig = px.bar(data_canada, x='year', y='pop')
    if input == 'B':
        fig = px.bar(data_canada, x='year', y='lifeExp')

    fig.show()

So what I need from here is how to create drop down menus that is an input to this function.

1
  • 1
    Do you need to do it necessarily with plotly_express or can you also use the whole plotly library? Commented Oct 14, 2020 at 13:42

1 Answer 1

1

One way to solve this is to use updatemenus, where you basically update the visibility of the two traces, based on the selection in the dropdown:

import plotly.express as px
data_canada = px.data.gapminder().query("country == 'Canada'")

fig = px.bar(data_frame=data_canada, x='year', y=['pop', 'lifeExp'], title="LifeExp") # Plotly 4.8 and above!

fig.update_layout(
    showlegend=False, # hide the legend so the default is not confusing
    updatemenus=[
        dict(
            active=0,
            buttons=list([
                dict(label="LifeExp",
                     method="update",
                     args=[{"visible": [False, True]},
                           {"title": "LifeExp"}]),
                dict(label="Population",
                     method="update",
                     args=[{"visible": [True, False]},
                           {"title": "Population"}])
            ])
        )]
)

This should give the following result with the Gapminder data example: enter image description here

What happens here is the following: First, you generate the figure with 2 traces and a default legend. Then, you add the dropdown and you make it control the visibility of the traces. The first option in the dropdown will be the default.

Note: this support for "wide-format" selection of columns is only available from Plotly 4.8.2 and higher (all numeric types are considered "the same" in wide-format from that version on

Sign up to request clarification or add additional context in comments.

6 Comments

Great, thank you. Would this work any differently if I had multiple charts and two drop downs?
If you have multiple charts, each one should be its own figure (or subplot) with its own drop downs. If you want to replace the whole chart completely, maybe it's worth looking into some more complex dashboard solution like Dash or Panel. Also, adding more dropdowns to the same chart is easy, just add another dict() to updatemenus. See "Update Several Data Attributes" section here: plotly.com/python/dropdowns What you need to be careful for is the positioning of the drowdowns, as they will be drawn on top of each other unless you specify the positions concretely.
Great, I appreciate the advice. I'd prefer to have the user only have to select the drop downs once. The project is to have the user select a tax reform for a child allowance and a state and it generates a bunch of charts to show the impact. We'd prefer they not have to select the reform and state for each new chart if possible. I created another stack overflow question to see if anyone knows how to do this. stackoverflow.com/questions/64356844/…
@tania Your suggestion raises a ValueError: Plotly Express cannot process wide-form data with columns of different type. on my end. I'm on version '4.8.1'
@vestland you are right, this was actually fixed in 4.8.2 apparently: community.plotly.com/t/… In 4.8.1 you can circumvent it by casting the columns into the same type (e.g. df.pop.astype(int)). I'll update the answer.
|

Your Answer

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