0
votes

I would like to install a dropdown filter in python plotly - without using dash.

The solution I came up with works in case that xaxis/yaxis ranges do not change, e.g. a heatmap. In case the ranges change, it does not work well anymore.

Example: A barchart with country information. Works well for Italy and Canada. If I switch to Germany with higher population numbers than the initial country Italy, the yaxis range does not increase. How could this be fixed? Or is there a more efficient way in general?

Thanks a lot for helpful suggestions!

Example:

# Data
df = px.data.gapminder()
df = df[['country','year', 'pop']]
df.head(3)
# Create Barchart
def generate_barchart(ins):
    fig = px.bar(df[df['country']==ins], x='year', y='pop')
    return fig

# Dropdown: Content
uplist1 = ['Italy', 'Canada', 'Germany']
uplist2 = [generate_barchart(ins) for ins in uplist1]

# Dropdown: Implementation
upfilter = [{'method': 'animate', 'label': i1, 'args': [i2]} for i1, i2  in zip(uplist1, uplist2)]
updatemenus = [{'buttons': upfilter}]

# Initial barchart
fig = go.Figure(uplist2[0])

# Add dropdown
fig.update_layout(updatemenus=updatemenus)

# Result
fig

Works well for Italy and Canada: enter image description here

Outside range: enter image description here

1

1 Answers

0
votes

I see two options how to make the Y axis right (besides manually resetting it). Both set range for Y axis.

  1. This alreay almost it, except the animation is a bit off (bars may go beyond or out of the viewport).

    def generate_barchart(ins):
        plot_df = df[df['country'] == ins]
        fig = px.bar(plot_df, x='year', y='pop')
        fig.update_yaxes(range=[plot_df['pop'].min(), plot_df['pop'].max()])
        return fig
    

    To fix it you can disable animation effect by making buttons this way.

    upfilter = [
        {
            'method': 'animate', 
            'label': i1, 
            'args': [
                i2, 
                {
                    'frame': {'duration': 0, 'redraw': False},
                    'mode': 'immediate',
                    'transition': {'duration': 0},
                },
            ]
        } 
        for i1, i2 in zip(uplist1, uplist2)
    ]
    
  2. Alternatively you can define the range across countries.

    def generate_barchart(ins):
        fig = px.bar(df[df['country'] == ins], x='year', y='pop')
        fig.update_yaxes(range=[
            df[df['country'].isin(uplist1)]['pop'].min(), 
            df[df['country'].isin(uplist1)]['pop'].max(),
        ])
        return fig