-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Marimekko aka Mekko plot #4019
Comments
Here is an implementation based on @nicolaskruchten work on #4461 : def stacked_bar_width_plot(df, value_cols, width_col, colors=None, **subplot):
"""A stacked column plot with variable bar width.
:param df
:param list value_cols: columns of `df`, already normalized (sum=1 for every line).
:param str width_col: column of `df`, unbounded, used (i) as label (ii) to compute width.
:param dict subplot: optional figure/row/col
"""
categories = df.index.to_list()
width = df[width_col]
htmpl = width_col + ': %{customdata}, %{y}'
x = np.cumsum([0] + list(width[:-1]))
colors = colors or [None, ] * len(value_cols)
figure = subplot.pop('figure', go.Figure())
for colname, color in zip(value_cols, colors):
figure.add_trace(go.Bar(name=colname, x=x, y=df[colname], width=width, hovertemplate=htmpl, customdata=width, offset=0, marker_color=color), **subplot)
return figure.update_xaxes(
tickvals=x + np.array(width) / 2,
ticktext=categories,
range=[0, np.sum(width)], **subplot
) \
.update_yaxes(tickformat=',.0%', range=[0, 1], row=subplot.get('row'), col=subplot.get('col')) \
.update_layout(barmode='stack', bargap=0)
def mekko_plot(df, unit_name=None, colors=None, **subplot):
"""A mekko plot is a normalized stacked column plot with variable bar width.
:param DataFrame df: already indexed by category, with only numeric columns:
there will be one stacked-bar per line (X), labeled after the index, with one bar per column.
:param str unit_name: used to populate hover.
:param list colors: color of each column. None for default palette (blue, red, ...).
The rest (title..) is easily added afterwards.
"""
# Normalize then defer to stacked_bar_width_plot plot.
value_cols = df.columns
w = pd.DataFrame({unit_name: df.sum(axis='columns')})
w[value_cols] = df.div(w[unit_name], axis='index')
return stacked_bar_width_plot(w, value_cols, width_col=unit_name, colors=colors, **subplot)
# Example
df = pd.DataFrame(dict(category=['a','a', 'b', 'b', 'a','a', 'b', 'b'],
var1=[9,2,5,3,2,4,6,0],
var2=[1,2,3,4,2,6,7,8])).set_index('category')
display(df)
mekko_plot(df, unit_name='some_label', colors=['blue', 'red']) |
Is there a way to assign a single color to a column in this code? I have a large mekko with many individual stacks - I'd rather have each column have a single color. Any suggestions? |
Many thanks, great job! |
Hi - we are trying to tidy up the stale issues and PRs in Plotly's public repositories so that we can focus on things that are still important to our community. Since this one has been sitting for several years, I'm going to close it; if it is still a concern, please add a comment letting us know what recent version of our software you've checked it with so that I can reopen it and add it to our backlog. Thanks for your help - @gvwilson |
Placeholder issue for discussing the addition of this kind of trace. See also #2901 for a circular variant, #4020 for the more-than-two-level variant and #1038 for the general-purpose treemap variant.
Here's a representative example of what this could look like:
Note that this is quite bar-like with two continuous axes, but also has non-linear category labels above.
This one doesn't have a (visible) continuous x-axis:
The text was updated successfully, but these errors were encountered: