plotly / plotly/dash

Ghost categories are displayed after bar chart is updated with subset of categories.

Open
#3,105 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3
Dominant language
Python
Stars
24.4k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
13

Description

Environment

Arch Linux x86_64 6.12.1-arch1-1, using Brave Browser Version 1.73.91 Chromium: 131.0.6778.85 (Official Build) (64-bit) and Firefox 133.0 (64-bit).

# pip list | grep dash
dash                 2.18.2
dash-core-components 2.0.0
dash-html-components 2.0.0
dash-table           5.0.0

# python -V
Python 3.12.7

Describe the bug

Bar charts draw nonexistent categories if a plot is updated with data that contains only a subset of the original categories. Here's a self-contained MWE demonstrating the problem.

from dash import Dash, dcc, callback, Output, Input
import plotly.express as px

app = Dash()
app.layout = [
    dcc.RadioItems(["include foo", "exclude foo"], "include foo", id="choice"),
    dcc.Graph(id="graph"),
]

@callback(
    Output("graph", "figure"),
    Input("choice", "value"),
)
def update(choice):
    if choice == "include foo":
        x = ["a", "b", "foo"]
        y = [ 0 ,  2 ,   1  ]
    else:
        x = ["a", "b"]
        y = [ 0 ,  2 ]

    p = px.bar(x=x, y=y)
    p.update_xaxes(categoryorder="total ascending")
    return p

app.run(debug=True)

Initially, or when include foo is selected, a bar chart is drawn with three categories a, b and foo, as expected:

If, however, exclude foo is selected afterwards and data for only two of the formerly three categories is used to generate the new plot, the excluded foo category is still retained in the plot and is displayed as having a value of zero.

From a little experimentation I gathered that this bug occurs only if the following conditions are met:

  • The category order on the x-axis has to be set. For example, removing the call to update_xaxes() will make the bug not surface.
  • One of the non-ghost categories has to have a value of zero. For example, if for both choices the value of a is set to something other than zero everything works as expected.

Note that the data sent from the dash server to the browser client is correct for both paths, i.e. if exclude foo is selected only data for a and b is sent and received. So this bug seems to live in javascript-land, maybe some sort of caching issue during plot updates. Also, somebody else had (has?) a similar problem using streamlit's plotly bindings. I'll link it here for reference: https://github.com/streamlit/streamlit/issues/5902

If there's more information I can provide, let me know.

Cheers.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the self-contained Dash MWE with dcc.Graph, the callback, px.bar, and update_xaxes(categoryorder="total ascending"). Inspect the browser-side Plotly update behavior when switching from three categories to two, especially when the remaining zero-valued category is present. Done means the excluded category is no longer displayed while the remaining categories and their values stay correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, plotly, python
Domain
data-visualization, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.