plotly / plotly/plotly.py

Empty Facets on partially filled MultiIndex DataFrame with datetime.date in bar plot

Open
#4,415 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3 sev-2
Dominant language
Python
Stars
18.8k
Forks
2.8k
Avg merge
16h 26m
Merged PRs (30d)
21

Description

I have a pandas dataframe with a multicolumn index consisting of three levels, which I want to plot using a plotly.express.bar. First dimension Station (str) goes into the facets, the second dimension Night (datetime.date) goes onto the x-axis and the third dimension Limit (int) is going to be the stacked bars.

The bug is, that the resulting figure does not show any data on facets which do only have data at one Night. The expected outcome would be that even though data exists only on one date this data is presented.

A reproducible example looks like this:

import datetime
import pandas as pd
import plotly.express as px

df = pd.DataFrame([
    ["station-01", datetime.date(2023,10,1), 50, 0.1],
    ["station-01", datetime.date(2023,10,1), 100, 0.15],
    ["station-01", datetime.date(2023,10,2), 50, 0.2],
    ["station-01", datetime.date(2023,10,2), 100, 0.22],
    ["station-01", datetime.date(2023,10,3), 50, 0.05],
    ["station-01", datetime.date(2023,10,3), 100, 0.02],
    ["station-02", datetime.date(2023,10,1), 50, 0.5],
    ["station-02", datetime.date(2023,10,1), 100, 0.2],
    ["station-03", datetime.date(2023,10,1), 50, 0.5],
    ["station-03", datetime.date(2023,10,1), 100, 0.5],
], columns=["Station", "Night", "Limit", "Relative Duration"])
df = df.set_index(["Station", "Night", "Limit"])

px.bar(
    df,
    x=df.index.get_level_values("Night"),
    y="Relative Duration",
    range_y=[0, 1],
    color=df.index.get_level_values("Limit"),
    facet_col=df.index.get_level_values("Station"),
)

The figure created looks like this:
newplot (2)

When replacing the datetime.date type by a string the figure looks like expected:

import datetime
import pandas as pd
import plotly.express as px

df = pd.DataFrame([
    ["station-01", "101", 50, 0.1],
    ["station-01", "101", 100, 0.15],
    ["station-01", "102", 50, 0.2],
    ["station-01", "102", 100, 0.22],
    ["station-01", "103", 50, 0.05],
    ["station-01", "103", 100, 0.02],
    ["station-02", "101", 50, 0.5],
    ["station-02", "101", 100, 0.2],
    ["station-03", "101", 50, 0.5],
    ["station-03", "101", 100, 0.3],
], columns=["Station", "Night", "Limit", "Relative Duration"])
df = df.set_index(["Station", "Night", "Limit"])

px.bar(
    df,
    x=df.index.get_level_values("Night"),
    y="Relative Duration",
    range_y=[0, 1],
    color=df.index.get_level_values("Limit"),
    facet_col=df.index.get_level_values("Station"),
)

newplot (3)

Due to this behavior I suspect the plot yielded from the initial data frame is false and there is a bug inside of the plotly.express code.

Thanks for helping out.

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 provided reproducible example through plotly.express.bar and compare the datetime.date and string cases. Trace the facet and date-axis handling from that entry point; the fix is complete when facets with data for only one Night still display their bars for datetime.date values.

Written by the indexing model from the issue text.

Assessment

Tech stack
pandas, python
Domain
data-visualization
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.