2

I am plotting chart using below code:

fig = px.line(df, x='Time', y=['one','two'], color= df.index)
fig['layout']['xaxis']['autorange'] = "reversed"
fig.update_layout(legend_title="Price")
fig.show()

Dataframe i am working with like is below:

      Time   one    two
100   9:30   129    243
110  10:30   234    453
120  11:00   155    234

Want to add dropdown menu to select from index and show one row at a time in chart. example if i select 110 from drop down it should only show chart for that row. Is there any easy fix for it. Thank you in adavance.

2
  • You've already received working solution, but would you care for a Plotly Dash approach as well? Commented Nov 18, 2020 at 20:32
  • @vestland yes please Commented Nov 19, 2020 at 5:18

1 Answer 1

2

Here's my solution:
In order to set the proper options for the dropdown menu, it would be helpful to have a function that creates the list of options (shown below)

# Create proper buttons list
def makeButtonsList(idxs):
    buttons = []
    for i, idx in enumerate(idxs):
        visibleArr = np.full((2*df.index.shape[0],), 
                             False, dtype=bool)       # 2x number of booleans since one/two vals are separate plots
        visibleArr[2*i] = True                        # Set two booleans next to each other (representing one & two) to true
        visibleArr[(2*i)+1] = True
        buttons.append(dict(label=str(idx),
                            method='update',
                            args=[{'visible': list(visibleArr)}]))    # 'Visible' arg determines which plots are shown 
                                                                      # depending on which dropdown is selected 
    return buttons

Next create the traces for the data (with your sample data, I created a bar chart but you could easily modify this)

traces = []
for i in range(df.Time.shape[0]):
    rowData = df.iloc[i, :]
    time = rowData.Time
    one = rowData.one
    two = rowData.two
    traces.append(go.Bar(x=[time], y=[one], name='One'))
    traces.append(go.Bar(x=[time], y=[two], name='Two'))

where df is the dataframe you are working with.

Finally put it all together and create the Plotly plot!

# Import packages
import pandas as pd
import numpy as np

import plotly.graph_objs as go
import plotly.express as px

# Create proper buttons list
def makeButtonsList(idxs):
    buttons = []
    for i, idx in enumerate(idxs):
        visibleArr = np.full((2*df.index.shape[0],), 
                             False, dtype=bool)       # 2x number of booleans since one/two vals are separate plots
        visibleArr[2*i] = True                        # Set two booleans next to each other (representing one & two) to true
        visibleArr[(2*i)+1] = True
        buttons.append(dict(label=str(idx),
                            method='update',
                            args=[{'visible': list(visibleArr)}]))    # 'Visible' arg determines which plots are shown 
                                                                      # depending on which dropdown is selected 
    return buttons

# Create traces
traces = []
for i in range(df.Time.shape[0]):
    rowData = df.iloc[i, :]
    time = rowData.Time
    one = rowData.one
    two = rowData.two
    traces.append(go.Bar(x=[time], y=[one], name='One'))
    traces.append(go.Bar(x=[time], y=[two], name='Two'))

# Create figure
fig = go.Figure(data=traces)

# Add dropdown options
fig.update_layout(
    updatemenus=[
        dict(
            buttons=makeButtonsList(df.index),
            direction="down",
            pad={"r": 10, "t": 10},
            showactive=True,
            x=0.55,
            xanchor="left",
            y=1.2,
            yanchor="top"
        ),
    ]
)


# Add annotation for index selected
fig.update_layout(
    annotations=[
        dict(text="Index:", showarrow=False,
        x=0, y=1.15, yref="paper", align="left")
    ],
    xaxis_title = 'Time',
    yaxis_title = 'Value',
)

# Show the plot
fig.show()

Here is a sample plot: Plot1

BONUS: If you think this method is tedious, and a slider bar would do the job just fine, Plotly supports animation of bar charts. Here is the following code you could use:

fig = px.bar(df, x='Time', y=['one','two'], animation_frame=df.index)
fig.update_layout(title='Data', barmode='group')
fig.show()

Here is the resulting plot: Plot2

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

5 Comments

it throws me an error on this line "for i in range(df2.Time.shape[0]):" as "AttributeError: 'NoneType' object has no attribute 'Time'". My time column is set as 12 hour with AM/PM . Can you please help me fix this issue
@Zac It seems that either you don’t have a df2 variable (this it is of type None) or the the df2 data frame variable has no column Time
I have everything in place its just that TIme column is as object and is write as 10:20 PM format. dataframe i have. please help me get it fix .
@Zac Since you just need to loop through all the rows in the dataframe df, you should be able to modify the for loop to for i in range(df.shape[0]):
its working but it only shows one data at a time i have same multiple index number with different time frame please check the link i have explained it better in this.

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.