0

I want to create a line plot in which the underlying data can be selected over a drop down menu. The data is in a pandas dataframe and I am using plotly_express.

I tried to use this post as a basis but it does not use plotly_express and the data is not in a pandas dataframe.

I have this code in which I define a data1 and data2 and then put those into the buttons. I am converting those dataframes into a dictionnary because if not I will have the error that dataframes were not "json-able".

# making two new dataframes out of the all-data dataframe (for drop down select)
dfe_deworming=dfe.loc['Deworming needed'].reset_index()
dfe_anemia=dfe.loc['Anemia'].reset_index()

# making the parameters for each button

#button 1
data1=dict(dfe_deworming)
x1=dfe_deworming.Month
y1=dfe_deworming.Count
color1=dfe_deworming.Facility

#button2
data2=dict(dfe_anemia)
x2=dfe_anemia.Month
y2=dfe_anemia.Count
color2=dfe_anemia.Facility

#initial plot
fig_deworming = px.line(data_frame=data1,x=x1,y=y1,color=color1)

# update menus
updatemenus = [
    {
        'buttons': [
            {
                'method': 'restyle',
                'label': 'Deworming needed',
                'args': [
                    {'data_frame':[data1],'x': [x1],'y':[y1],'color':[color1]},
                ]
            },
            {
                'method': 'restyle',
                'label': 'Anemia',
                'args': [
                    {'data_frame':[data2],'x': [x2],'y':[y2],'color':[color2]},
                ]
            }
        ],
        'direction': 'down',
        'showactive': True,
    }
]


fig_deworming.update_layout(
    updatemenus=updatemenus
)

fig_deworming.update_traces(mode='markers+lines')

fig_deworming.show()

In its initial state it looks good. However if I try to select an option, all lines get exactly the same dataset. It could be the combination of all the different datasets.

Those pictures illustrate the problem:

First option of the drop down menu after first selection

Second option of the drop down menu after second selection

2

1 Answer 1

0

fundamentally you need to use graph object parameter structure for updatemenus

  • have generated a dataframe that appears to match your structure
  • create the graph using plotly express
  • generate updatemenu which are parameters you would pass to go.Scatter
  • used a list comprehension as each menu is really the same
  • finally fix an issue with trace generated by plotly express for hovertemplate
import numpy as np
import pandas as pd
import plotly.express as px

# generate a dataframe that matches structure in question
dfe = (
    pd.DataFrame(
        {
            "Month": pd.date_range("1-jan-2020", freq="M", periods=50).month,
            "Facility": np.random.choice(["Deworming needed", "Anemia"], 50),
            "Count": np.random.randint(5, 20, 50),
        }
    )
    .groupby(["Facility", "Month"], as_index=False)
    .agg({"Count": "sum"})
)

# the line plot with px...
fig = px.line(
    dfe.loc[dfe.Facility.eq("Deworming needed")], x="Month", y="Count", color="Facility"
)


# fundametally need to be working with graph object parameters not express parameters
updatemenus = [
    {
        "buttons": [
            {
                "method": "restyle",
                "label": f,
                "args": [
                    {
                        "x": [dfe.loc[dfe.Facility.eq(f), "Month"]],
                        "y": [dfe.loc[dfe.Facility.eq(f), "Count"]],
                        "name": f,
                        "meta": f,
                    },
                ],
            }
            for f in ["Deworming needed", "Anemia"] # dfe["Facility"].unique()
        ],
        "direction": "down",
        "showactive": True,
    }
]

fig = fig.update_layout(updatemenus=updatemenus)

# px does not set an appropriate hovertemplate....
fig.update_traces(
    hovertemplate="Facility=%{meta}<br>Month=%{x}<br>Count=%{y}<extra></extra>",
    meta="Deworming needed",
)

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

Comments

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.