Filter Dataframe based on Dropdown Filter for px.timeline

Continuing the discussion from Creating a DrownDown Filter for px.timeline:

Hi @Dabi ,

Because of the previous post is mark as solved, I will try to response another post by creating new topics.

As the code shown above, you use update method on dropdown.

update method is used to modify the data and layout sections of the graph.

So you need to create multiple plots (in this case is px.timeline) and put it together into a Figure object (which mean fig variable) .

The multiple plot will be switched one another based on your choice on dropdown menu.

The reason why your plot got blank canvas when you change the dropdown values, is because you just create a plot so when you set visible properties as True, it just will give effect only on the first index.

If I understand your response well, what you really need is the filtered dataframe by Customer value on every option in the dropdown , and show the plot a customer with Task as the legend.

  1. When I click on the Customer, can I then filter the dataframe and then pass the new args to the timeline plot to then regenerate the plot (same way as the legend would accomplish. ??

NO, as far as I know you can not put filtered dataframe to args value. BUT you can create multiple plots based on filtered datafarame and swith to show one another using dropdown.

So as I implement it to code, it will be something like below.

import plotly.express as px
import pandas as pd
import plotly.offline as pyo

# read data from excel
df = pd.read_excel('path/file.xlsx')

# create timeline for certain customer (blue) by filtering the dataframe
# which is it will create 4 timeline charts, because there is 4 customers
for idx, customer in enumerate(df.Customer.unique()):
    df_filtered  = df[df.Customer == customer]
    print(customer, df_filtered)
    if idx==0:
        fig = px.timeline(df_filtered,x_start=df_filtered['Start'],x_end=df_filtered['End'],y="Product",color="Task")
        # hide the plot
        fig.update_traces(visible=False)
    else:
        fig1 = px.timeline(df_filtered,x_start=df_filtered['Start'],x_end=df_filtered['End'],y="Product",color="Task")
        # hide the plot
        fig1.update_traces(visible=False)
        fig.add_trace(fig1.data[0])

fig.update_yaxes(autorange="reversed")

fig.update_layout(
    updatemenus=[
        dict(
            active=4,
            type="dropdown",
            showactive=True,
            buttons=list(
                [
                    dict(
                        label=cust,
                        method="update",
                        args=[
                            {
                                "visible": [
                                    True if c == cust else False for c in df["Customer"].unique().tolist()+[None]
                                ]
                            }
                        ],
                    )
                    for cust in df["Customer"].unique().tolist()+[None]
                ]
            ),
        )
    ]
)
fig.show()

I hope this result is what you are looking for.
timeline_plot_part2

As a newbie , my actual application is for work and Is there a way I can share with you directly my dilemma for privacy??.

I think you can send personal message to another members, to prevent it as public post.

Have a good day!

1 Like