✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Automatically adjust plot axis range after filtering data


I’m kind of confused with Dash’s behavior when filtering data.
In few words, I have a bar plot, where each bar is a country. This bar plot is connected to a dropdown that filters out countries. But, even if I filter out the country associated to the maximum, the range won’t change. A couple images might help:

You see, after filtering out United States (even if I filter it by default), Dash still “remembers” that US was the maximum. I’d like the y-axis range to be automatically updated so the maximum shown is about 1.2M, in this case. If matplotlib can do that, I’m sure this could be done here.

This is the relevant code:

                      value=['United States'],

And then:

@app.callback(Output(component_id='tests', component_property='figure'),
              [Input(component_id='filter-tests', component_property='value')])
def plot_tests(countries):
    dte = data[~data.isin(countries)]
    fig = go.Bar(x=dte['country'], y=dte['cumulative_tests'])
    fig.update_yaxes(tickformat='.1%', row=3, col=1, autorange=True)
    return fig

My actual code is a 3x1 subplot grid, but I guess that doesn’t matter. Is there any method to make my y-axis update when changing the plotting data?

Hm, i haven’t seen this before. auto range is indeed what should happen between plots. Could you try to create a simple, reproducible example that demonstrates the issue? That’ll help us determine if it’s an issue in the app code or indeed a bug. Thanks!

@chriddyp , I managed to create a minimal example:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objects as go
from dash.dependencies import Input, Output

app = dash.Dash(__name__)
server = app.server

df = pd.DataFrame(pd.DataFrame({'country': {0: 'Iceland',
  1: 'Bahrain',
  2: 'Norway',
  3: 'Estonia',
  4: 'Switzerland',
  5: 'Israel',
  6: 'Slovenia'},
 'test_million': {0: 102658.70704717531,
  1: 42367.37939352402,
  2: 23969.44609101287,
  3: 23037.322451160784,
  4: 22929.918218991366,
  5: 17042.22280880952,
  6: 16865.661240773756}}))

country_options = [{'label': i, 'value': i} for i in df.country.unique()]

app.layout = html.Div(children=[
    # Títulos

    # Gráfico testeos

@app.callback(Output(component_id='tests', component_property='figure'),
              [Input(component_id='filter-tests', component_property='value')])
def plot_tests(countries):
    dte = df[~df.isin(countries)].sort_values('test_million', ascending=False)[['country', 'test_million']].head(5)
    fig = go.Figure()
    fig.add_trace(go.Bar(x=dte['country'], y=dte['test_million']))

    return fig

You’ll se even if Iceland comes filtered by default, the range of my plot is still based on Iceland’s value.

Do you know what might be happening?