# How to adjust the X-axis order of boxplot with StatsPlots.jl

**URL:** <https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065>\
**Category:** Visualization\
**Tags:** plots, statsplots\
**Created:** [February 26, 2021, 5:12am UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065 "2021-02-26T05:12:56Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)\
**Post date:** [February 26, 2021, 5:12am UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/1 "2021-02-26T05:12:56Z")

</div>

```julia
using Plots, StatsPlots, DataFrames

df = DataFrame(
    id=repeat([3, 17, 21], inner=10),
    value=randn(30)
)

@df df boxplot(string.(:id), :value, fillalpha=0.75, linewidth=1)

```

The result is  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/e/9/e97a9be669a66dff40ac38e795727c1870ec1d1f.png)

I want the box to be 3, 17, 21 from left to right.

PS: I have also tried `CategoricalArray` for the `id` column, but nothing changed.

---

<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:** [February 26, 2021, 4:01pm UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/2 "2021-02-26T16:01:35Z")

</div>

Normally you can just pass `id` as the x values, but then the boxes will be in the correct numerical positions.  
In this case here, the best is probably just to replace 3, 17 and 21 with 1, 2 and 3 change the xticks to show 3, 17 and 21 - or to pad the values (they are sorted alphabetically)

```julia
@df df boxplot(lpad.(string.(:id), 2), :value, fillalpha=0.75, linewidth=1)

```

---

<div class="post-metadata">

**Author:** ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)\
**Post date:** [February 26, 2021, 4:10pm UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/3 "2021-02-26T16:10:49Z")

</div>

Thanks. I figured out a similar solution today (by replacing original id values with properly lexicographically ordered ones) but it seemed a little ugly and introduced unnecessary noise.

It is much better if there is some option like `order` to specify the order directly.

---

<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:** [February 26, 2021, 5:29pm UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/4 "2021-02-26T17:29:49Z")

</div>

What syntax would you suggest for that?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [February 26, 2021, 5:43pm UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/5 "2021-02-26T17:43:32Z")

</div>

For this type of problem, `@sprintf` is our best friend:

```julia
using Plots, StatsPlots, DataFrames, Printf

df = DataFrame(
    id=repeat([3, 17, 21], inner=10),
    value=randn(30)
)

str = [@sprintf("%02i", x) for x in df.id] 
@df df boxplot(str, :value, fillalpha=0.75, linewidth=1)

# or to keep similar syntax, one may define a sprintf02i() function:
sprintf02i(vecx) = [@sprintf("%02i", x) for x in vecx] 
@df df boxplot(sprintf02i(:id), :value, fillalpha=0.75, linewidth=1)

```

![StatsPlot_Boxplot_lexicographic_order](https://global.discourse-cdn.com/julialang/original/3X/0/5/05498b2eeb37d152055d17c506f8c43e8b14d99e.png)

---

<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:** [February 26, 2021, 7:24pm UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/6 "2021-02-26T19:24:53Z")

</div>

I personally prefer

```julia
lpad.(string.(:id), 2)

```

to

```julia
str = [@sprintf("%02i", x) for x in df.id] 

```

but that’s a question of taste I guess

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [February 26, 2021, 7:51pm UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/8 "2021-02-26T19:51:20Z")

</div>

@mkborregaard, sorry for having overlooked your answer, much simpler indeed.

---

<div class="post-metadata">

**Author:** ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)\
**Post date:** [February 27, 2021, 3:30am UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/9 "2021-02-27T03:30:04Z")

</div>

> [@mkborregaard](#):
>
> What syntax would you suggest for that?

Hi, @mkborregaard, I have no knowledge of internal details. But how about

```julia
@df df boxplot(string.(:id), :value, fillalpha=0.75, linewidth=1, xorder=[3, 17, 21])

```

Or we may pass into a custom `sort` function to sort the specific column in a `df`.

```julia
@df df boxplot(string.(:id), :value, fillalpha=0.75, linewidth=1, 
                         xsort=sort)

```

The above two `lpad` and `sprintf` workarounds work well for this particular example. But what if I want the order to be `21 3 17`? Of course, I can still find a workaround, but it does not look beautiful.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [February 27, 2021, 6:22am UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/10 "2021-02-27T06:22:36Z")

</div>

I happened to work a bit with boxplots yesterday. It would be really nice if there was a recipe for `Pair{String, AbstractArray}` so you could make a boxplot from `["a"=>[1,5,9], "b"=>[7,7,19]]`. I might just write one.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [February 27, 2021, 7:37am UTC](https://discourse.julialang.org/t/how-to-adjust-the-x-axis-order-of-boxplot-with-statsplots-jl/56065/11 "2021-02-27T07:37:24Z")

</div>

@Shuhua, the folllowing seems to work by left-right padding spaces, if _elegance_ is not a concern:

```julia
using Plots, StatsPlots, DataFrames

df = DataFrame(
    id=repeat([3, 17, 21], inner=10),
    value=randn(30)
)
xorder = [21 3 17]
Nx = length(xorder)
str = fill("",length(df.id))
for (i,xi) in enumerate(xorder)
    j = findall(x->x==xi, df.id)
    si = " "^(Nx-i)
    @. str[j] = si * string(df.id[j]) * si
end

# solution by left-right space-padding strings
@df df boxplot(str, :value, fillalpha=0.75, linewidth=1)

```

![StatsPlot_Boxplot_lexicographic_order3](https://global.discourse-cdn.com/julialang/original/3X/3/6/36986c2586dd3d742aa2e5ca4f0522db35637d20.png)
