plotly.py icon indicating copy to clipboard operation
plotly.py copied to clipboard

Stacked grouped bar chart

Open RenaudLN opened this issue 1 year ago • 4 comments
trafficstars

What's new

Adds a new figure factory for grouped stacked bar charts

import plotly.express as px
import plotly.figure_factory as ff

df = px.data.tips().groupby(["day", "sex", "smoker"])[["total_bill", "tip"]].sum().reset_index()

fig = ff.create_grouped_stacked_bar(
    df,
    x="smoker",
    stack_group="sex",
    color="day",
    y="tip",
    category_orders={"day": ["Thur", "Fri", "Sat", "Sun"]},
)
fig.show()

image

import plotly.express as px
import plotly.figure_factory as ff

df = px.data.tips().groupby(["day", "sex", "smoker"])[["total_bill", "tip"]].sum().reset_index()

fig = ff.create_grouped_stacked_bar(
    df,
    x="sex",
    stack_group="day",
    color="smoker",
    y="tip",
    category_orders={"day": ["Thur", "Fri", "Sat", "Sun"]},
    template="seaborn",
    stack_group_gap=0.33,
    bar_gap=0.02,
)
fig.show()

image

Issues: #2976 #3251

Documentation PR

  • [x] I've seen the doc/README.md file
  • [x] This change runs in the current version of Plotly on PyPI and targets the doc-prod branch OR it targets the master branch
  • [x] If this PR modifies the first example in a page or adds a new one, it is a px example if at all possible
  • [ ] Every new/modified example has a descriptive title and motivating sentence or paragraph
  • [x] Every new/modified example is independently runnable
  • [x] Every new/modified example is optimized for short line count and focuses on the Plotly/visualization-related aspects of the example rather than the computation required to produce the data being visualized
  • [x] Meaningful/relatable datasets are used for all new examples instead of randomly-generated data where possible
  • [x] The random seed is set if using randomly-generated data in new/modified examples
  • [x] New/modified remote datasets are loaded from https://plotly.github.io/datasets and added to https://github.com/plotly/datasets
  • [x] Large computations are avoided in the new/modified examples in favour of loading remote datasets that represent the output of such computations
  • [x] Imports are plotly.graph_objects as go / plotly.express as px / plotly.io as pio
  • [x] Data frames are always called df
  • [x] fig = <something> call is high up in each new/modified example (either px.<something> or make_subplots or go.Figure)
  • [x] Liberal use is made of fig.add_* and fig.update_* rather than go.Figure(data=..., layout=...) in every new/modified example
  • [x] Specific adders and updaters like fig.add_shape and fig.update_xaxes are used instead of big fig.update_layout calls in every new/modified example
  • [x] fig.show() is at the end of each new/modified example
  • [x] plotly.plot() and plotly.iplot() are not used in any new/modified example
  • [x] Hex codes for colors are not used in any new/modified example in favour of these nice ones

Code PR

  • [x] I have read through the contributing notes and understand the structure of the package. In particular, if my PR modifies code of plotly.graph_objects, my modifications concern the codegen files and not generated files.
  • [x] I have added tests (if submitting a new feature or correcting a bug) or modified existing tests.
  • [x] For a new feature, I have added documentation examples in an existing or new tutorial notebook (please see the doc checklist as well).
  • [x] I have added a CHANGELOG entry if fixing/changing/adding anything substantial.
  • [x] For a new feature or a change in behaviour, I have updated the relevant docstrings in the code to describe the feature or behaviour (please see the doc checklist as well).

RenaudLN avatar Jan 20 '24 06:01 RenaudLN

Thanks @RenaudLN! This functionality is fantastic. My hesitation though is that we really want this built into plotly.js, and I think we have most of the pieces in place to make that happen, so it shouldn't be very hard to finish. It would be confusing if we add this and soon after create a different and preferred way to do the same thing.

@archmoj can you look into what more we need to add for plotly.js to create stacked grouped bars natively?

alexcjohnson avatar Jan 30 '24 16:01 alexcjohnson

Hey @alexcjohnson I agree it would be best to support this natively but it's already been open for 4 years 🙂 https://github.com/plotly/plotly.js/issues/4914

There is a way to do stacked-grouped bars currently but it requires setting the x-axis (for vertical bars) as array of arrays which can make the axis very crowded (I'm thinking timeseries for instance). Also there is no way to control the spacing between groups with this method. image

Compared to this image

Something I would love to see if you do implement it natively is automatically declining the base colorscale colors within each stack (each stack is assigned a color from the colorscale then varied on the lightness scale for the components of the stack).

RenaudLN avatar Feb 10 '24 00:02 RenaudLN

Any update on this?

RenaudLN avatar Apr 08 '24 04:04 RenaudLN

Any update on this?

Hi @RenaudLN I still need to investigate possibility of implementing this in plotly.js. I could start looking into that (in few days) right after next plotly.js minor is out. Thanks :pray:

archmoj avatar Apr 08 '24 13:04 archmoj

There is now a PR open on plotly.js repository. Please see https://github.com/plotly/plotly.js/pull/7009

archmoj avatar Jun 03 '24 13:06 archmoj