How to set labels for eached coloured bar in Plots.jl's bar()?

bar(
    ["a","b","c"],
    [1,2,3],
    fillcolor = categorical(["a","b","c"]).refs,
    labels = ["a","b","c"]
)

I can make the plot with the above code, but I can’t seem to work out how to make the labels follow the same colours and text. I tried doing a group= but the bar_position = :dodge isn’t implemented.

1 Like

Have you tried groupedbar instead?

Yes. It’s causing an error see https://github.com/JuliaPlots/StatPlots.jl/issues/129

In principle it should be possible to just pass each bar as a separate series:

bar(
    ["a" "b" "c"],
    [1 2 3],
    labels = ["a" "b" "c"]
)

I say “in principle” because there appears to be a problem with passing just one series at a time.
So the way you’re doing it should be the best workaround. The only thing that doesn’t seem to work is the legend, which you want to say the exact same thing as the x labels. Could I ask you why? When would you do that?

I filed the issue: the problem is that the series with only one bar (that one would get by grouping) doesn’t work.

I find the legend generally not very useful when working with bar plots (the information is generally on the axis already) but it helped us uncover a few things to fix in Plots. I’ve opened an umbrella issue at Plots about horizontal layout.

1 Like

Actually in my benchmarks I want those from Julia to be of a different colour to those from R

bar(
    ["a" "b" "c"],
    [1 2 3],
    labels = ["a" "b" "c"],
    bar_width = 1
)

is already possible. https://github.com/JuliaPlots/Plots.jl/pull/1414 allows

bar(
    ["a" "b" "c"],
    [1 2 3],
    labels = ["a" "b" "c"],
)

as well.

3 Likes

Great @piever!
@xiaodai for sure, I was just wondering why you’d want to duplicate that information in the legend.

Awesome @daschw :slight_smile: Nice timing on the comment…

Good point, hadn’t thought about helping Plots find the default bar_width. Nice job with the fix!

A bit overkilled for this, but (now?) in StatsPlots you can use group to group the serie over any given array:

For bars:

vals = [1,2,3]
cats = ["a","b","c"]
colorMap = Dict("a"=>"red","b"=>"blue","c"=>"green")
labelMap = Dict("a"=>"cat a","b"=>"cat b","c"=>"cat c")
colours = [colorMap[i] for i in cats]
labels = [labelMap[i] for i in cats]
bar(cats,vals,colour=colours,group=labels, legend=:topleft)

barexample

A case where this approach could be more useful:

colors = [y == 1 ? "blue" : "red" for y in y]
labels = [y == 1 ? "benign" : "malign" for y in y]
scatter(X[:,1],X[:,2], colour=colors, title="Classified tumors",xlabel="Tumor Radius", ylabel="Tumor Texture", group=labels)

cancerplot

2 Likes

I’m not sure what the idea is here?