Bar chart generates unwanted extra bars from a previously selected chart

When I toggle radio buttons to create different bar charts sometimes extra, empty leftover bars appear from the previously selected chart.



Notice how the cities from “Similar Police Budget Size” appear when I return back to “Cities in the Same Region”

This is the callback that creates the bar charts:

# Comparison charts
@app.callback(Output('compareFig', 'figure'),
              [Input('submit-button', 'n_clicks'),
              Input("city-dropdown", "value"),
              Input("compareby", "value")]
             )
def city_comparisons(n_clicks,City,compareby):
    if n_clicks is None:
        raise PreventUpdate
    else:
        compareFig = px.bar()
        if (compareby =='Similar CRI Values'):
            #find indices of cities with similar CRIs and make mini dataframe

            index = similar_cri.index[similar_cri['City']==City].tolist()[0]
            similar_cri.iloc[index-2:index+3]
            if (index<2):
                #don't want negative indexing
                similarCRICities = similar_cri.iloc[0:6]
            else:
                similarCRICities = similar_cri.iloc[index-3:index+4]

            # make graph from iloc
            compareFig = px.bar(similarCRICities,
                               x="City",
                               y="CRI",
                               text='CRI',
                               title='Cities with most similar CRI values to '+City
                              )

        elif (compareby =='Similar Budget Size'):
            total_spending = city_groupby.first().sort_values('Total Spending').reset_index()
            index = total_spending.index[total_spending['City']==City].tolist()[0]
            if (index<3):
                similarSpendingCities = total_spending.iloc[0:6]
            else:
                similarSpendingCities = total_spending.iloc[index-3:index+4]
            compareFig = px.bar(similarSpendingCities,
                               x="City",
                               y="Total Spending",
                               color='CRI',
                               text='Total Spending',
                               color_continuous_scale=[[0,"darkblue"], [1,"lightgreen"]],
                               title='Cities with similar sized 2020 budgets compared to '+City
                              )
            compareFig.update_traces(texttemplate='%{text:.2s}')
            compareFig.update_layout(xaxis={'categoryorder':'total descending'},uniformtext_minsize=8, uniformtext_mode='hide')

        elif (compareby =='Cities in the Same Region'):
            # use region groupby to show all cities from the same region
            region = region_dct[City]
            cities_in_region = region_groupby.get_group(region).groupby('City').first().reset_index()
            compareFig = px.bar(cities_in_region,
                               x="City",
                               y="CRI",
                               color='CRI',
                               text='CRI',
                               range_color=[-1,1],
                               color_continuous_scale=[[0,"darkblue"], [1,"lightgreen"]],
                               title='CRI of cities in the ' + region + " region"
                              )
            compareFig.update_layout(xaxis={'categoryorder':'total descending'})
        elif (compareby == 'Similar Police Budget Size'):
            index = police_spending.index[police_spending['City']==City].tolist()[0]

            if (index<3):
                similarPoliceSpending = police_spending.iloc[0:6]
            else:
                similarPoliceSpending = police_spending.iloc[index-3:index+4]
            compareFig = px.bar(similarPoliceSpending,
                               x="City",
                               y="Dollar Amount",
                               color='CRI',
                               text='Dollar Amount',
                               range_color=[-1,1],
                               color_continuous_scale=[[0,"darkblue"], [1,"lightgreen"]],
                               title='Cities with similar sized 2020 police department budgets compared to '+City
                              )
            compareFig.update_traces(texttemplate='%{text:.2s}')
            compareFig.update_layout(xaxis={'categoryorder':'total descending'},uniformtext_minsize=8, uniformtext_mode='hide')

        return compareFig

This is the setup for my data - there’s a few different dataframe structures depending on the comparison being made.

city_spending = pd.read_csv('city_spending_all_years.csv').drop(['Unnamed: 0'],axis=1)
city_groupby = city_spending.groupby(['City'])
region_groupby = city_spending.groupby(['Region'])
police_spending = city_spending[(city_spending['Spending Type'] == 'Police') & (city_spending['Year'] =='2020')]
similar_cri = city_groupby.first().sort_values('CRI').reset_index()

Here’s the layout for this part of the app:

dbc.Row([
      dbc.Col(dcc.Graph(id='compareFig'),width=6,),
      dbc.Col(
            dbc.RadioItems(
                  id='compareby',
                  options=[{'label': i, 'value': i} for i in ['Similar CRI Values','Similar Budget Size',
                                "Cities in the Same Region",'Similar Police Budget Size']],
                  value='Similar CRI Values',
                  labelStyle={'display': 'inline-block'}
                  ),
             width=3,
             style={'text-align':'left'}),
      ],
       align='center',
       justify='center'
)

Anyone know how to fix this?

Hi @syrup

Too extrange :thinking:

Print compareFig before returning and see if the Output of the callback is the same in both cases. :woozy_face: