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.

1 Like

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))
2 Likes

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:

1 Like