More Barplots

Hi all. Round two of figuring out bar plots in Makie. Given the data, I would like to plot one set of data and then stack the other data on top of it. In my last question, my issue was resolved with the n_dodge attribute being adjusted, but there doesn’t seem to be a similar attribute for stacking the plots. As of now, I can only plot one data set or the other. Bonus points if you include a legend. Any help would be greatly appreciated.

using CairoMakie

porosity_op = [80,75,77,80,85,90,85]
porosity_tot = [20,21,21,20,23,26,20]
grades = ["ZXF-5Q","ACF-10Q","AXF-3Q","AXF-5Q","AXM-5Q","AXZ-5Q","TM"]

fig = CairoMakie.Figure()
ax = CairoMakie.Axis(fig[1,1], xticks = (1:7, grades), title = "Porosity Percentage")
barplot!(ax2, 1:7,
porosity_tot,
stack = [1,2,1,2,1,2,1], width = 0.5,
) 
 
barplot!(ax, 1:7,
porosity_op,
stack = [1,2,1,2,1,2,1], width = 0.5
)
fig

Hey, brother. If I was using vanilla Makie.jl, I might do something like this if I wanted to keep the datasets separate:

using CairoMakie

fig = Figure()

ax = Axis(fig[1, 1]; xticks = (eachindex(grades), grades), title = "Porosity Percentage")

barplot!(ax, porosity_op;
    color = :cornflowerblue,
    width = 0.5,
    label = "Operational",
)

barplot!(ax, porosity_tot;
    offset = porosity_op,
    color = :orange,
    width = 0.5,
    label = "Total",
)

Legend(fig[1, 2], ax, "Porosity")

fig

or just use AoG if the dataset can be expressed in “long” format:

using CairoMakie, AlgebraOfGraphics

set_aog_theme!() # Looks nice

df_long = (
    porosity = [porosity_op; porosity_tot],
    grp = repeat(["Operational", "Total"]; inner = 7),
    grades = repeat(grades, 2),
)

plt = data(df_long) *
    mapping(:grades => presorted, :porosity => "",
        stack = :grp,
        color = :grp => "Porosity",
    ) *
    visual(BarPlot, width = 0.5)

draw(plt; axis = (; title = "Porosity Percentage"))

or wide format too:

df_wide = (
    porosity_op = [80,75,77,80,85,90,85],
    porosity_tot = [20,21,21,20,23,26,20],
    grades = ["ZXF-5Q","ACF-10Q","AXF-3Q","AXF-5Q","AXM-5Q","AXZ-5Q","TM"],
)

plt = data(df_wide) *
    mapping(:grades => presorted,
        [:porosity_op, :porosity_tot] .=> ["Operational", "Total"];
        stack = dims(1),
        color = dims(1) => "Porosity",
    ) *
    visual(BarPlot, width = 0.5)

draw(plt; axis = (; title = "Porosity Percentage", ylabel = ""))

Can adjust to taste for how the percentages should combine

Using tidy/long-format data can save many headaches. Makie stack and color attributes appear to expect it.

The reason stack doesn’t have nstack like ndodge is that dodging is data independent but stacking is not. So you can’t stack with separate plot objects as all the data has to be available at once to compute the cumsums. There’s generally no crosstalk between separate Makie plot objects.

In my original code, the values are extracted from a tidy format data frame. I switched it around from wide format for the very reason you mentioned as it happens :laughing:

So I would combine the two data sets and then set the stack that way? Is that the logic?

Good looking out brother, this result is exactly what I was looking for. I’ve never used AoG though. I started using Makie because of how much control it gives you (since I guess you can consider it “low level” or backend), and most things seem easy enough to achieve. Does AoG make CairoMakie that much easier to use? I get the vibe you mainly use AoG, so if you’re down I’d really appreciate your thoughts on it.

Yes. AoG does the concatenation for you if there are more datasets, that’s why this particular thing is more convenient there.

For sure, glad it worked out. I’d say I reach for AlgebraOfGraphics.jl if I am working with structured data, and Makie.jl otherwise these days. The nice thing is that it’s pretty doable to go back and forth if you ever need to too. And much appreciation to Jules and the rest of the Makie team. Their revamp of the AoG Palmer Penguins tutorial and wider packages in general really helped things start to click for me

When you say structured data, you mean things like data frames, right? Would unstructured data be something like, plotting a function? I haven’t used much outside of CairoMakie, so I think I’ve mostly only worked with structured data; things like experimental observations and the like.
Also, wow, didn’t even realize one of the creators was helping me! Makes sense how he just knew exactly what my issues were both times!

Right, data frames (or other Tables.jl compatible objects), named tuples, etc. If I’m just making a one-off plot or something simple like plotting vector x vs. vector y, I might reach for something like scatter(x, y) from vanilla Makie.jl first, although you could always do the same in AoG with mapping(x, y) |> draw.

And once things like grouping and categories start to come into the picture, AoG really becomes a natural choice depending on the context. Nowadays, working with long vs. wide data, or even so-called “pre-grouped” data is pretty pleasant.

Yea, this community is dope. Besides getting to just chat with folks that are world experts in their fields, what’s really kept me coming back is the straight up kindness and inclusiveness from everyone involved.