I'm trying to create a double bar stacked bar chart using plotly.
I found this code:
from plotly import graph_objects as go
data = {
"original":[15, 23, 32, 10, 23],
"model_1": [4, 8, 18, 6, 0],
"model_2": [11, 18, 18, 0, 20],
"labels": [
"feature",
"question",
"bug",
"documentation",
"maintenance"
]
}
fig = go.Figure(
data=[
go.Bar(
name="Original",
x=data["labels"],
y=data["original"],
offsetgroup=0,
),
go.Bar(
name="Model 1",
x=data["labels"],
y=data["model_1"],
offsetgroup=1,
),
go.Bar(
name="Model 2",
x=data["labels"],
y=data["model_2"],
offsetgroup=1,
base=data["model_1"],
)
],
layout=go.Layout(
title="Issue Types - Original and Models",
yaxis_title="Number of Issues"
)
)
Source: https://dev.to/fronkan/stacked-and-grouped-bar-charts-using-plotly-python-a4p
This works, but I need to take it one step further if possible. I need the various models to able to appear on either side of each set of bars as I'm adding another parameter (yes on the left and no on the right). In the example, blue is always on the left bar and orange and/or green are always on the right. I'm looking for a way so that any of those colors could appear on both the left and right of a set of bars, but with different values. i.e. in the example feature has a blue bar count of 15, but maybe on the right side of feature blue has a value of 5.
you can use dynamic stacking with calculated base values and consistent color coding, maintaining exactly 10 bars -5 categories × 2 sides- while supporting variable component combinations per bar. also chekc this out stacked + grouped bar chart
from plotly import graph_objects as go
data = {
"left": [
{"original": 15, "model_1": 4, "model_2": 11},
{"original": 23, "model_1": 8, "model_2": 18},
{"original": 32, "model_1": 18, "model_2": 18},
{"original": 10, "model_1": 6, "model_2": 0},
{"original": 23, "model_1": 0, "model_2": 20}
],
"right": [
{"original": 7, "model_1": 3, "model_2": 5},
{"original": 12, "model_1": 6, "model_2": 8},
{"original": 15, "model_1": 8, "model_2": 10},
{"original": 5, "model_1": 4, "model_2": 0},
{"original": 10, "model_1": 2, "model_2": 12}
],
"labels": [
"feature",
"question",
"bug",
"documentation",
"maintenance"
]
}
fig = go.Figure()
colors = {
"original": "#636EFA",
"model_1": "#EF553B",
"model_2": "#00CC96"
}
def add_stacked_bar(side, offset_group):
side_data = data[side]
for i, category in enumerate(data["labels"]):
current_base = 0
for model_type in ["original", "model_1", "model_2"]:
value = side_data[i].get(model_type, 0)
if value > 0:
fig.add_trace(go.Bar(
name=f"{model_type.replace('_', ' ').title()} ({side.title()})",
x=[category],
y=[value],
offsetgroup=offset_group,
base=current_base,
marker_color=colors[model_type],
legendgroup=model_type,
showlegend=(i == 0)
))
current_base += value
add_stacked_bar("left", 0)
add_stacked_bar("right", 1)
fig.update_layout(
title="Issue Types - Original and Models",
yaxis_title="Number of Issues",
barmode='group',
legend_title="Model Types",
legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1
)
)
fig.show()