Plotly.js - stacked bars in subplots

Hi all,

I’m trying to plot stacked bars with PlotlyJS. It looks ok, when I use just one plot, but when I combine two plots together, the bars are no longer stacked.

Example:

using PlotlyJS, Dates

dates = [Date(2021, 05, 08), Date(2021, 05, 09), Date(2021, 05, 10)]
trace1 = bar(; x = dates, y = [15, 1, 6], name = "Buy - euro", barmode="stack")
trace2 = bar(; x = dates, y = [2, 5, 4], name = "Buy - usd", barmode="stack")
tracesBuy = [trace1, trace2]

layout = Layout(;barmode="stack")
p1 = plot(tracesBuy, layout)

The plot looks good, the bars are stacked:

But when I add another plot, they are not stacked anymore.

trace3 = bar(; x = dates, y = [-10, -5, -8], name = "Sell - euro", barmode="stack")
trace4 = bar(; x = dates, y = [-15, -6, -3], name = "Sell - usd", barmode="stack")
tracesSell = [trace3, trace4]
p2 = plot(tracesSell, layout)
[p1, p2]

Any ideas, what’s wrong here?

I guess barmode should be specified for the subplots layout.

p = [p1, p2]
p.plot.layout["barmode"] = "stack"
p

Yes, that exactly did it! Thank you.
How did you figured that out? I’m pretty new to plotlyjs, so I probably missed that in doc.

@stej
barmode is an attribute of layout, not of the bar trace.
In your definition:

trace1 = bar(; x = dates, y = [15, 1, 6], name = "Buy - euro", barmode="stack")

and similarly, trace2, trace3, trace4,
barmode="stack"
is ignored, because it isn’t recognized as an attribute for bar.
That’s why the barmode must be set for the new plot, p. It doesn’t inherit the layout for p1 and p2.

Yes, that’s right, my fault.
I didn’t pay attention to that as I thought that I already specified layout for both p1 and p2. So I didn’t try to specify layout mode for the parent. I didn’t event know how to do it (didn’t know about the p.plot.layout["barmode"] = "stack" setting).

So is it true, that the p1 and p2 loose their layout when they are used in a subplot? Or how does that work?

@stej
To convince yourself, print after the definition of each plot the corresponding json serialization and inspect the layout attribute for each one:

p1 = plot(tracesBuy, layout)
print(json(p1, 2))
p2 = plot(tracesSell, layout)
print(json(p2, 2))

and

p= [p1; p2]
print(json(p, 2))

Then set `barmode=“stack” for the ayout of the plot p, and print again:

print(json(p, 2))

This post was referenced from other one, so I looked once again.

My code:

using PlotlyJS, Dates

layout = Layout(;barmode="stack")
dates = [Date(2021, 05, 08), Date(2021, 05, 09), Date(2021, 05, 10)]
tracesBuy = [bar(; x = dates, y = [15, 1, 6], name = "Buy - euro", barmode="stack")
             bar(; x = dates, y = [2, 5, 4], name = "Buy - usd", barmode="stack")]
p1 = plot(tracesBuy, layout)
tracesSell = [bar(; x = dates, y = [-10, -5, -8], name = "Sell - euro", barmode="stack")
              bar(; x = dates, y = [-15, -6, -3], name = "Sell - usd", barmode="stack")]
p2 = plot(tracesSell, layout)

p = [p1, p2]
p.plot.layout["barmode"] = "stack"
p

It works in VS Code with Julia addon.
When I select julia code and run “Send current line or selection to REPL”, it looks like this:

If I just run julia from cmd.exe, and paste the same code, I get

Not sure what’s going on here :confused: