Plots: bars side by side

Hi there,

I’m using Plots.jl (with PyPlot as the backend) and trying to plot some bars side by side, as in the following example from matplotlib: http://matplotlib.org/examples/api/barchart_demo.html (figure below)

Looking at the documentation of Plots it seemed to me that the attribute I wanted might be bar_position = :stack, but it didn’t work out :confused: the bars are still overlapping.

Can anyone help with this plot?

Thanks in advance!

2 Likes
3 Likes
mn = [20, 35, 30, 35, 27,25, 32, 34, 20, 25]
sx = repeat(["Men", "Women"], inner = 5)
std = [2, 3, 4, 1, 2, 3, 5, 2, 3, 3]
nam = repeat("G" .* string.(1:5), outer = 2)

using StatPlots
groupedbar(nam, mn, yerr = std, group = sx, ylabel = "Scores", 
        title = "Scores by group and gender")

03

9 Likes

Or, to get something closer to your example, you can modify a little:

groupedbar(nam, mn, yerr = std, group = sx, ylabel = "Scores", 
        title = "Scores by group and gender", bar_width = 0.67, 
        lw = 0, c = [:red :darkkhaki], markerstrokewidth = 1.5,
        framestyle = :box, grid = false, yticks = 0:5:35)

04

8 Likes

Thanks very much @ChrisRackauckas and @mkborregaard. Now with mkborregaard’s examples I can make it the way I wanted

Somehow I missed the StatPlots package :sweat_smile:

1 Like

Maybe it’s a good idea to include this as an example to the README of StatPlots?

Just from looking at the one provided now on GitHub I wouldn’t be able to get my plot the way I wanted to

You’re welcome to put a strong example together and submit a PR :slight_smile:

1 Like

The syntax in the StatPlots readme uses matrix inputs - that’s also valid but less common:

men = [20, 35, 30, 35, 27]
women = [25, 32, 34, 20, 25]
std_men = [2, 3, 4, 1, 2]
std_women = [3, 5, 2, 3, 3]

groupedbar(["G1", "G2", "G3", "G4", "G5"], [men women], yerr = [std_men std_women])

There is a tiny example with grouping in groupedbar in the StatPlots README, right below the matrix example, showing how to use the group syntax, but admittedly it’s easy to overlook.

@kaslusimoes : it’s shameless self-advertising, but if you need to do some data preprocessing (for example compute mean and sem or std, or some other type of error across all observation or across some variable) before the plot, you could check out the groupedbar examples from GroupedErrors

In this last form, how can you specify the legend for different color bars ?

Sorry, I could not find the doc but the solution is trivial : add ,label=["first","second"].

Hi there, I desperately try to label the individual bars, as in the original example 20, 25, … etc. I tried adding series_annotations like this

using StatsPlots

men = [20, 35, 30, 35, 27]
women = [25, 32, 34, 20, 25]
std_men = [2, 3, 4, 1, 2]
std_women = [3, 5, 2, 3, 3]

groupedbar(
  ["G1", "G2", "G3", "G4", "G5"],
  [men women],
  yerr = [std_men std_women],
  series_annotations = [string.(men), string.(women)]
)

results in a plot with misaligned annotations:
Screenshot from 2020-09-19 22-17-31
A second run results in a plot with the top cut off and an error message
“GKS: Rectangle definition is invalid in routine SET_VIEWPORT” .
Please help!

1 Like

Welcome to Julia!

Please refrain from posting on an old thread for new help. Please open a new thread for this question.

Additionally, please read PSA: Make it easier to help you. In particular, your code is not an MWE. We can’t help you without a reproducible example.

1 Like

Note the comma in the series_annotations vector - this will create a column rather than a row vector, which is the wrong orientation for Plots.

julia> [1 2]
1×2 Array{Int64,2}:
 1  2

julia> [1, 2]
2-element Array{Int64,1}:
 1
 2

So try without the comma in your labels.

Thanks for your answer. Sadly it doesn’t help.

[men, women]

gives a

2-element Array{Array{Int64,1},1}

which I find appropriate for a groupedbar.

But let’s switch over to the new topic I created at pdeffebach’s request:
https://discourse.julialang.org/t/how-to-annotate-a-groupedbar-plot/46938