Empty Facets on partially filled MultiIndex DataFrame with datetime.date in bar plot
Nobody has claimed this yet.
- 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:
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"),
)
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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