简体   繁体   中英

plotly graph_objects (go) selecting two lines from two dropdowns menu to compare in the same figure

i am trying to compare two lines in the same fig in plotly go, the goal is to let the user to select two entities (ie countries) from two dropdown menu in the chart

this is the chart with all entities active

when i select different country in the two dropdown: ie dropdown1 = Italy, dropdown2= France the chart shows just one line (the last selected from the dropdown, so it update)but it doesn't plot the two lines in the same figure

Plot with just one line

this is the dataframe: dataframe head

this is the code i am working on:

fig1 = go.Figure()
for column in df.columns.to_list():
        fig1.add_trace(
            go.Scatter(
                x = df.index,
                y = df[column],
                name = column
            )
        )
        
button_all = dict(label = 'All',
                      method = 'restyle',
                      args = [{'visible': df.columns.isin(df.columns),
                               'title': 'All',
                               'showlegend':True}])
button_none = dict(label = 'None',
                      method = 'update',
                      args = [{'visible': df.columns.isin(df.columns),
                               'title': 'All',
                               'showlegend':True}])

def create_layout_button(column):
        return dict(label = column,
                    method = 'restyle',
                    args = [{'visible': df.columns.isin([column]),
                             'title': column,
                             'showlegend': True}])
    
def create_layout_buttonE(column):
        return dict(label = column,
                    method = 'update',
                    args = [{'visible': df.columns.isin([column]),
                             'title': column,
                             'showlegend': True}])
    
addAll = True
# Update plot sizing
fig1.update_layout(
    width=700,
    height=500,
    autosize=False,
    margin=dict(t=120, b=0, l=0, r=0),
)


# Add dropdowns
button_layer_1_height = 1.08
fig1.update_layout(
    updatemenus=[
        dict(
            buttons=([button_all] * addAll) + list(df.columns.map(lambda column: create_layout_button(column))),
            direction="down",
            pad={"r": 10, "t": 0},
            showactive=True,
            x=0.1,
            xanchor="left",
            y=button_layer_1_height,
            yanchor="top"
        ),
        dict(
            buttons=([button_none] * addAll) + list(df.columns.map(lambda column: create_layout_buttonE(column))),
            direction="down",
            pad={"r": 10, "t": 0},
            showactive=True,
            x=0.37,
            xanchor="left",
            y=button_layer_1_height,
            yanchor="top"
        ),
    ]
)



fig1.show()
  • synthesized dataframe in same structure as you defined
  • taken a different approach. Rather than creating all traces and controlling visibility in updatemenus . Create two traces and control name and contents of y in updatemenus
import pandas as pd
import numpy as np
import plotly.graph_objects as go

# get some countries 
countries = (
    pd.read_csv(
        "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/vaccinations/locations.csv"
    )
    .loc[lambda d: d["iso_code"].str.len() == 3, "location"]
    .sample(20)
    .sort_values()
    .values
)

# build data frame of same struct
df = pd.DataFrame(
    np.random.randint(200, 1500, [22, len(countries)]),
    columns=countries,
    index=range(2000, 2022),
)

# create a figure with two place holder traces
fig = go.Figure(
    [
        go.Scatter(x=df.index, y=np.full(len(df), np.nan), meta=i, name=i)
        for i in range(2)
    ]
)

# but data for y and name in when country is selected
fig.update_layout(
    updatemenus=[
        {
            "x": b / 3,
            "y": 1.4,
            "active": None,
            "buttons": [
                {
                    "label": c,
                    "method": "restyle",
                    "args": [{"y": [df[c]], "name": c}, [b]],
                }
                for c in df.columns
            ],
        }
        for b in range(2)
    ]
)

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM