# StatPlots groupedbar order x axis

**URL:** <https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912>\
**Category:** Visualization\
**Tags:** statsplots\
**Created:** [August 23, 2018, 12:46am UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912 "2018-08-23T00:46:23Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![stelmo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stelmo/32/6242_2.png) [@stelmo](https://discourse.julialang.org/u/stelmo)\
**Post date:** [August 23, 2018, 12:46am UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/1 "2018-08-23T00:46:23Z")

</div>

Hi,

Is there a way to order the x-axis bars using groupedbar? Currently it is placing the individual bars alphabetically, but I would like to specify the order manually. I have tried using plot!(xticks=(1:10, labels)), but that only changes the actual labels and doesn’t move the bars…

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [August 23, 2018, 8:36am UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/2 "2018-08-23T08:36:48Z")

</div>

No, and you can’t specify the order of the individual sub-bars either. But you should be able to do that IMHO. If you can think of a good set of keywords and interface to specify this (perhaps `group` could take a tuple where the second arg is the group order, and there could be an `xorder` argument? not sure) you should open an issue on StatPlots and we’ll implement this. Perhaps @piever has a good idea, he’s thought a lot about these things.

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [August 23, 2018, 9:53am UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/3 "2018-08-23T09:53:44Z")

</div>

I though categorical arrays used to work for this? Normally to specify the order of your data you can put your array into a `CategoricalArray` (see [here](https://github.com/JuliaData/CategoricalArrays.jl)). I think in that case Plots should sort by the custom order.

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [August 23, 2018, 3:00pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/4 "2018-08-23T15:00:37Z")

</div>

That works for the groups, but unfortunately not for the `x` argument. I guess the solution is to implement that in StatPlots and add it to the readme.

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [August 23, 2018, 3:50pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/5 "2018-08-23T15:50:46Z")

</div>

Yes that needs fixing: if the user specifies an order with the `CategoricalArray` we should respect that in the x axis: am a bit confused as to why it doesn’t work already, but will investigate.

---

<div class="post-metadata">

**Author:** ![stelmo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stelmo/32/6242_2.png) [@stelmo](https://discourse.julialang.org/u/stelmo)\
**Post date:** [August 23, 2018, 3:57pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/6 "2018-08-23T15:57:54Z")

</div>

I see you added the issue, thanks!

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [August 23, 2018, 6:58pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/7 "2018-08-23T18:58:03Z")

</div>

Yes, perhaps this needs fixing in Plots rather than StatPlots? Even if it means taking on a dep on CategoricalArrays (but that shouldn’t be necessary, no?)

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [August 23, 2018, 10:21pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/8 "2018-08-23T22:21:07Z")

</div>

I also think this should be fixed on Plots side but it shouldn’t need extra dependency: we should instruct Plots to respect the order of the custom type before converting to string / float

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [August 24, 2018, 10:20am UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/9 "2018-08-24T10:20:15Z")

</div>

I’m actually no longer sure I completely understand what you are trying to achieve, could you post the code you’re using to generate the plot?

I’m a bit confused because I don’t think the order used by default for the `x` axis is alphabetical so I wanted to make sure I understand the issue.

Related to this, we could probably allow to use `groupedbar(["a", "a", "b", "b"], [1,2,3,4])` to give the same plot as `groupedbar(["a", "b"], [1 2; 3 4])`, currently it errors.

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [August 24, 2018, 1:30pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/10 "2018-08-24T13:30:50Z")

</div>

Agreed.

---

<div class="post-metadata">

**Author:** ![stelmo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stelmo/32/6242_2.png) [@stelmo](https://discourse.julialang.org/u/stelmo)\
**Post date:** [August 24, 2018, 5:50pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/11 "2018-08-24T17:50:58Z")

</div>

Sure, so in this example I would like to have the x-axis arranged B, C, A (as an arbitrary example). By using xtick=(…,…) it changes only the actual labels, it doesn’t change the columns. So the column should move with the label.

> using Plots  
> using StatPlots  
> using GroupedErrors  
> using DataFrames  
> gr()
> 
> df = DataFrame([[“A”,“B”,“A”,“B”,“A”,“B”,“C”,“C”,“C”], [1,2,3,2,3,4,6,6,8]], [:Observation, :Count])  
> @\> df begin  
> @across :all  
> @x \_.Observation :discrete

> ```
> @y _.Count
> @plot groupedbar(ylabel="Fraction of proteome", legend=true)
> 
> ```
> 
> end

 ![test.png](https://global.discourse-cdn.com/julialang/original/3X/6/7/67cc1d21e10512237e824cadc126290cb7dfb040.png)

Does this make sense?

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [August 25, 2018, 5:38pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/12 "2018-08-25T17:38:30Z")

</div>

Minor remark: use the `</>` button to format your code, the `"` button makes a quotation and it looks a bit funky.

Interestingly enough GroupedErrors already does the correct thing and you can use CategoricalArrays:

```julia

using Plots
using StatPlots
using GroupedErrors
using DataFrames
using CategoricalArrays
gr()
v = CategoricalArray(["A","B","A","B","A","B","C","C","C"])
levels!(v, ["B", "C", "A"])
df = DataFrame([v, [1,2,3,2,3,4,6,6,8]], [:Observation, :Count])
@> df begin
    @across :all
    @x _.Observation :discrete

    @y _.Count
    @plot groupedbar(ylabel="Fraction of proteome", legend=true)
end

```

See the [CategoricalArrays docs](https://juliadata.github.io/CategoricalArrays.jl/stable/using.html) for more details. I think you should also be able to make a column categorical from the DataFrame directly, something like:

```julia
df = DataFrame([["A","B","A","B","A","B","C","C","C"], [1,2,3,2,3,4,6,6,8]], [:Observation, :Count])
categorical!(df, :Observation)
levels!(df[:Observation], ["B", "C", "A"])

```

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [August 25, 2018, 5:47pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/13 "2018-08-25T17:47:07Z")

</div>

Solving the thing in general for StatPlots is a bit trickier: should `groupedbar(x, y, group=z)` return the `x` axis in the order it is encountered or should it sort it, like `boxplot` and `violinplot` do? Maybe we could sort it.

I almost think plotting commands where sorting is possible should take the same keyword arguments as `sort` (`rev`, `by`) to allow reversing the order or some custom sorting.

---

<div class="post-metadata">

**Author:** ![stelmo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stelmo/32/6242_2.png) [@stelmo](https://discourse.julialang.org/u/stelmo)\
**Post date:** [August 25, 2018, 8:39pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/14 "2018-08-25T20:39:12Z")

</div>

Okay, this fix works for GR, but when using PyPlot it doesn’t show the actual x-axis labels (see the image, although I can manually fix this using the xticks attribute). For both Plotly and PlotlyJS it just crashes. Thanks for all your help so far!

 ![newimg](https://global.discourse-cdn.com/julialang/original/3X/f/1/f1b5b086184e9ec2ee1cd2ea2520ad3d709e5753.png)

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [August 25, 2018, 9:06pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/15 "2018-08-25T21:06:12Z")

</div>

This sounds like a bug on Plots side, could you open an issue over there?

---

<div class="post-metadata">

**Author:** ![stelmo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stelmo/32/6242_2.png) [@stelmo](https://discourse.julialang.org/u/stelmo)\
**Post date:** [August 25, 2018, 9:16pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/16 "2018-08-25T21:16:37Z")

</div>

Will do!

---

<div class="post-metadata">

**Author:** ![newb\_gk](https://avatars.discourse-cdn.com/v4/letter/n/e19b73/32.png) [@newb\_gk](https://discourse.julialang.org/u/newb_gk)\
**Post date:** [October 22, 2019, 5:59pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/17 "2019-10-22T17:59:09Z")

</div>

Is there an update on this? I’m having the same sorting issue of the x axis with grouped bars on StatsPlots. It doesn’t seem to be an issue on Plots itself, but couldn’t figure out how to plot grouped bars with Plots using any of the backends.

---

<div class="post-metadata">

**Author:** ![JonasIsensee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonasisensee/32/4704_2.png) [@JonasIsensee](https://discourse.julialang.org/u/JonasIsensee)\
**Post date:** [June 12, 2020, 9:03am UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/18 "2020-06-12T09:03:25Z")

</div>

Hi,

so I just figured out how to do it after a lot of digging.

The issue is that in  
`RecipesPipeline.jl` there is  
`group_labels = sort(collect(unique(v)))`

> <https://github.com/JuliaPlots/RecipesPipeline.jl/blob/304db22c33b64a902dd91606a8886ec371f62809/src/group.jl#L11>

Now in theory there are `CategoricalArrays` for this purpose,  
however `unique(ctg::CategoricalArray)` returns an ordinary `Vector{String}` instead of a new `CategoricalArray`.

Defining this solves the problem in this case

```julia
function Base.unique(ctg::CategoricalArray)
    l = levels(ctg)
    newctg = CategoricalArray(l)
    levels!(newctg, l)
end

```

```julia
ctg = CategoricalArray(["a", "b", "c", "a", "b", "c"])
levels!(ctg, ["c", "b", "a"])
groupedbar(1:6, group=ctg)

```

![test](https://global.discourse-cdn.com/julialang/original/3X/2/9/29d383b3527553c22200dd2d450af5c0e0017cea.png)

---

<div class="post-metadata">

**Author:** ![jlawrie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlawrie/32/26283_2.png) [@jlawrie](https://discourse.julialang.org/u/jlawrie)\
**Post date:** [August 30, 2022, 10:00pm UTC](https://discourse.julialang.org/t/statplots-groupedbar-order-x-axis/13912/19 "2022-08-30T22:00:05Z")

</div>

> so I just figured out how to do it after a lot of digging.

- Thank you!

@JonasIsensee Just so as you know, in response to [this similar question](https://github.com/JuliaPlots/StatsPlots.jl/issues/437) on GitHub for StatsPlots.jl, I quickly wrote up your method into a function which adapts the usual inputs to `StatsPlots.groupedbar`, meaning that the ordering of the names and categories is preserved.

I credited you directly but I wasn’t able to tag you on GitHub, so I thought it would be kind to let you know.

Have a nice day!
