2

I have two scatter plots of two variables/arrays on same axis. I want to add a dropdown which updates the data of both variables/arrays.

import numpy as np
import pandas as pd
from plotly import graph_objects as go

scen3_df = pd.DataFrame(np.random.randint(10, 20, (100, 8)), columns=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
orig_df = pd.DataFrame(np.random.randint(0, 10, (100, 8)), columns=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

first_title = scen3_df.columns.to_list()[0]
traces = []
buttons = []
for idx, col in enumerate(scen3_df.columns):

    visible = [False]*8
    visible[idx] = True
    traces.append(go.Scatter(x=scen3_df.index, y=scen3_df[col],
                             name="Scenario 3",
                             visible = True if idx==0 else False,
                             ))

    traces.append(go.Scatter(x=scen3_df.index, y=orig_df[col],
                             name="Original",
                             visible = True if idx==0 else False,
                             ))

    buttons.append(dict(label=col,
                        method="update",
                        args=[{"visible": visible},
                              {"title": f" Gate operation at {col}"}]
                        ))


updatemenus = [{'active':0, "buttons":buttons}]

fig = go.Figure(data=traces,
                 layout=dict(updatemenus=updatemenus))
fig.update_layout(title=first_title, title_x=0.5)
fig.update_yaxes(range=[0, scen3_df.max()], title="Gate Height (m)")
fig.update_xaxes(title="Time (Julian Day)")
fig.show()
fig.write_html("gate_operations.html")

What I want What I want

What I am currently getting What I get

1 Answer 1

1
  • consistency is always the key when building these types of figure and menus
  • it's far simpler to achieve consistency with Plotly Express so I have switched to this instead of graph objects
  • build two figures for the two data frames, then integrate them. Name is overridden to ensure legend appears as you want
  • having built figure, have all required information within it to build menu as nested list comprehensions
import numpy as np
import pandas as pd
import plotly.express as px

scen3_df = pd.DataFrame(np.random.randint(10, 20, (100, 8)), columns=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
orig_df = pd.DataFrame(np.random.randint(0, 10, (100, 8)), columns=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])



# generate equivalent figures for both data frames
figs = [
    px.line(df, y=df.columns)
    .update_traces(line_color=color, name=name)
    .for_each_trace(lambda t: t.update(visible=t.legendgroup == df.columns[0]))
    for df, color, name in zip(
        [scen3_df, orig_df], ["blue", "red"], ["Scenario 3", "Original"]
    )
]

# construct overall figure
fig = (
    figs[0]
    .add_traces(figs[1].data)
    .update_layout(xaxis_title="Time (Julian Day)", yaxis_title="Gate Height (m)")
)
# build the menu
fig.update_layout(
    updatemenus=[
        {
            "buttons": [
                {
                    "label": col,
                    "method": "update",
                    "args": [
                        {"visible": [t.legendgroup == col for t in fig.data]},
                        {"title": f" Gate operation at {col}"},
                    ],
                }
                for col in scen3_df.columns
            ]
        }
    ]
)

enter image description here

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

2 Comments

Thank you for your answer. One reason for using low level graph objects was that I would later like to add multiple dropdown menus each of which will have impact on data being displayed. Is this also possible using plotly express?
yep - look at code example I've provided. I'm using graph objects model to build menus... the menus are not built with px, but low level API.

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.