For an example on how to make a stacked bar chart with the specific dataset provided, take a look at the suggestion in Plotly-Dash: Want two stacked bar charts side by side from single df column. The following answer addresses how you can not make a stacked bar chart with a single trace. To show you why, I'll start with what may seem like redundant details. But hopefully everything will be clear in the end.
In plotly terms, trace
is used to describe a graph object
such as Scatter
or Bar
like in the snippet below.
Snippet 1.1:
import plotly.graph_objs as go
fig = go.Figure(go.Bar(x=['CategoryA', 'CategoryB', 'CategoryC'],
y=[20, 14, 23]))
fig.update_layout(template = 'plotly_dark').show()
If you look at the snippet above, you'll see that that is a bar chart with a single trace in the form of go.Bar(x=['CategoryA',...
.
Plot 1.1:
Now, how can we add something to make it a stacked chart
? If you start out by adding an element to x
like 'CategoryD'
, then nothing happens. And that's a bit interesting since you'd might expect an error message instead.
Plot 1.2: Added x value
Snippet 1.2
import plotly.graph_objs as go
fig = go.Figure(go.Bar(x=['CategoryA', 'CategoryB', 'CategoryC', 'CategoryD'],
y=[20, 14, 23]))
fig.update_layout(template = 'plotly_dark').show()
But nothing happens before CategoryD
has a corresponding y value like 15
:
Plot 1.3: Added x and y value
Conclusion so far: Adding values to x
and y
will add another category on the x-axis and a value on the y-axis. As you can see, nothing is getting stacked
here quite yet:
Snippet 1.3:
import plotly.graph_objs as go
fig = go.Figure(go.Bar(x=['CategoryA', 'CategoryB', 'CategoryC', 'CategoryD'],
y=[20, 14, 23, 15]))
fig.update_layout(template = 'plotly_dark').show()
But what if you add a layout term with barmode='stack'
?
Snippet 2:
import plotly.graph_objs as go
fig = go.Figure(go.Bar(x=['CategoryA', 'CategoryB', 'CategoryC', 'CategoryD'],
y=[20, 14, 23, 15]))
fig.update_layout(barmode='stack',
title = 'Stacked bar chart',
template = 'plotly_dark').show()
Plot 2: barmode='stack'
I can understand anyone hoping that this would stack all data within a single trace, but plotly just isn't built that way. To get what you need, you'll have to add another trace using fig.add_trace(go.Bar())
or simply fig.add_bar()
.
Snippet 3:
import plotly.graph_objs as go
fig = go.Figure(go.Bar(x=['CategoryA', 'CategoryB', 'CategoryC', 'CategoryD'],
y=[20, 14, 23, 15]))
fig.add_bar(x=['CategoryA', 'CategoryB', 'CategoryC', 'CategoryD'],
y=[5, 14, 4, 20])
fig.update_layout(barmode='stack',
title = 'Stacked bar chart!',
template = 'plotly_dark').show()
Plot 3: Add trace
Notice that neither of the go.Bar()
objects have had any name assigned to them, and that plotly by default names them trace 0
and trace 1
. So I guess it's more correct to say that a trace contains or 'shows' a plotly graph object rather than calling them the same thing. If you'd like to specify other names, you can do so with, for example, name = 'segment 1'
like this:
Snippet 4:
import plotly.graph_objs as go
fig = go.Figure(go.Bar(x=['CategoryA', 'CategoryB', 'CategoryC', 'CategoryD'],
y=[20, 14, 23, 15],
name = 'segment 1'))
fig.add_bar(x=['CategoryA', 'CategoryB', 'CategoryC', 'CategoryD'],
y=[5, 14, 4, 20],
name = 'segment 2')
fig.update_layout(barmode='stack',
title = 'Stacked bar chart!',
template = 'plotly_dark').show()
Plot 4: Add named traces
If you'd like to 'unstack' your bars, just change barmode to 'group'
like this:
fig.update_layout(barmode='group'),
Plot 5: