1

I would like to create a plotly plot where I can change the value of the plotly express color argument via a button. I am using plotly.express.scatter for this.

For example, the initial plot shown is px.scatter(df, "sepal_length", "sepal_width", color="species"). Changing from "species" to "petal length" in a dropdown menu would update the plot so that instead color="petal_length". If it makes a difference, "species" uses the default discrete color sequence while "petal_length" uses the default continuous color scale.

The code I have so far makes the initial plot and dropdown buttons, but choosing the buttons has no effect. I don't understand how to get the plotly express color argument passed through this Plotly.update interface.

import plotly.express as px
import pandas as pd


df = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv")
fig = px.scatter(df, "sepal_length", "sepal_width", color="species")

fig.update_layout(
    updatemenus=[
        dict(
            buttons=list([
                dict(
                    args=["color", "species"],
                    label="species",
                    method="update"
                ),
                dict(
                    args=["color", "petal_length"],
                    label="petal length",
                    method="update"
                ),
            ]),
            showactive=True,
            x=0.05,
            xanchor="left",
            y=1.06,
            yanchor="top"
        ),
    ]
)

fig.update_layout(
    annotations=[
        dict(text="color", x=0.015, xref="paper", y=1.05, yref="paper",
             align="left", showarrow=False),
    ])

fig.show()

Plotly scatterplot with dropdown menu

1 Answer 1

3

For color='species', three graphs are internally created for each categorical variable. And color='petal_length' consists of a single graph data. So, it is possible to handle this by setting the drop-down to show/hide the graph. The actual code reuses the data created by express.scatter. The data for each graph will be configured in a graph object; three will be shown and one will be hidden. Set the button to restyle as a function of the button.

import plotly.express as px
import plotly.graph_objects as go
import pandas as pd

df = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv")
fig1 = px.scatter(df, "sepal_length", "sepal_width", color="species")
fig2 = px.scatter(df, "sepal_length", "sepal_width", color="petal_length")

fig = go.Figure()
fig.add_trace(go.Scatter(fig1.data[0], visible=True))
fig.add_trace(go.Scatter(fig1.data[1], visible=True))
fig.add_trace(go.Scatter(fig1.data[2], visible=True))

fig.add_trace(go.Scatter(fig2.data[0], visible=False))

fig.update_layout(
    updatemenus=[
        dict(
            buttons=list([
                dict(
                    args=["visible", [True,True,True,False]],
                    label="species",
                    method="restyle"
                ),
                dict(
                    args=["visible", [False,False,False,True]],
                    label="petal length",
                    method="restyle"
                ),
            ]),
            showactive=True,
            x=0.05,
            xanchor="left",
            y=1.2,
            yanchor="top"
        ),
    ]
)

fig.update_layout(
    annotations=[
        dict(text="color", x=0.01, xref="paper", y=1.16, yref="paper",
             align="left", showarrow=False),
    ])
fig.update_layout(xaxis_title_text='sepal_length', yaxis_title_text='sepal_width', legend_title_text='species')
fig.show()

enter image description here

enter image description here

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

1 Comment

This works great, thanks! I was easily able to add a sepal_width choice too. I created a fig3 and added its trace like what you did with fig2. For the visible args in the button dicts I added new Falses at the ends for the first two and the new one is [False,False,False,False,True].

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.