# Theming coloured boxplots in Makie

**URL:** <https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552>\
**Category:** Visualization\
**Tags:** makie\
**Created:** [February 13, 2023, 12:00pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552 "2023-02-13T12:00:49Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![jewh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jewh/32/28586_2.png) [@jewh](https://discourse.julialang.org/u/jewh)\
**Post date:** [February 13, 2023, 12:00pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/1 "2023-02-13T12:00:49Z")

</div>

Can someone explain to me how to theme a `Makie` boxplot such that I can colour boxes by specific conditions or ‘groups’, and also control the colour palette for this via a custom theme?

I can alter colour palette via the theme, and have boxplot colours reflect this:

```julia
using CairoMakie

CairoMakie.activate!(type = "pdf")

my_theme = Theme(
    palette = (patchcolor = [:red, :green, :blue, :yellow, :orange, :pink],),
    )

set_theme!(my_theme)

fig = Figure(backgroundcolor=:grey90)

axs = Axis(fig[1, 1], aspect=AxisAspect(1))

x = Vector{Float64}(undef, 40)

for i = 1:40
    x[i] = i % 4
end 

CairoMakie.boxplot!(axs, x, rand(40))

ylims!(axs, 0, 1)

save("figures/testcairo.pdf", fig)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/1/7153eeb2ceb12165c313d0ed11c3b60a6ad9747a.png)

(Plot is all red, indicating it’s responding to my change in colours - the default colour scheme would plot this as blue)

However if I now try to colour the box plots by a condition (for instance, if the x-variable is even or not), the palette reverts to the default `Makie` colour scheme:

```julia
CairoMakie.boxplot!(axs, x, rand(40); color=map(x -> x % 2 == 0, x))

```

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

(You can see this is incorrect as I have no purple defined in my custom palette!)

How can I get the plot to respond to my custom colour palette?

---

<div class="post-metadata">

**Author:** ![jewh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jewh/32/28586_2.png) [@jewh](https://discourse.julialang.org/u/jewh)\
**Post date:** [February 13, 2023, 12:02pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/2 "2023-02-13T12:02:02Z")

</div>

Aware of closely related post [Coloring boxplot groups in Makie - #7 by piever](https://discourse.julialang.org/t/coloring-boxplot-groups-in-makie/62505/7), however the solution uses AlgebraOfGraphics, for which I can find less documentation on theming

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 13, 2023, 12:13pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/3 "2023-02-13T12:13:50Z")

</div>

Once you pass a vector of numbers as a color, these are looked up in the colormap by scaling with colorrange. To use a categorical colormap that way, set `colormap = my_colors, colorrange = (1, length(my_colors))`

---

<div class="post-metadata">

**Author:** ![jewh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jewh/32/28586_2.png) [@jewh](https://discourse.julialang.org/u/jewh)\
**Post date:** [February 13, 2023, 12:18pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/4 "2023-02-13T12:18:53Z")

</div>

> [@jules](#):
>
> colormap = my\_colors, colorrange = (1, length(my\_colors))

Brilliant, that (specifically:

```julia
my_colors = [:red, :green, :blue, :yellow, :orange, :pink]

my_theme = Theme(colormap = my_colors, colorrange = (1, length(my_colors)))

```

)

works perfectly. Thanks!

 ![image](https://global.discourse-cdn.com/julialang/original/3X/a/9/a9db73b933494030ba49ec3445bf67d96f9c6a9e.png)

---

<div class="post-metadata">

**Author:** ![jewh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jewh/32/28586_2.png) [@jewh](https://discourse.julialang.org/u/jewh)\
**Post date:** [February 13, 2023, 12:28pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/5 "2023-02-13T12:28:14Z")

</div>

This solution uses the first and last elements in `my_colors` for plotting. What’s the simplest means of having it use the order of elements in `my_colors`? i.e. for two conditions, use elements 1:2, for three conditions, use elements 1:3, and so on.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 14, 2023, 4:38pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/6 "2023-02-14T16:38:53Z")

</div>

Ah hm you use 0 and 1 for colors, my solution was based on the groups being numbered 1 to k and the colorrange going from 1 to n colors. That should perfectly map to categorical colors, not interpolated ones, as long as k is not larger than n. Can you pass colormap and colorrange directly to the boxplot? I don’t think a colorrange belongs in a theme usually, as it’s too data dependent (unless we force categorical color lookup with it like here)

---

<div class="post-metadata">

**Author:** ![jewh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jewh/32/28586_2.png) [@jewh](https://discourse.julialang.org/u/jewh)\
**Post date:** [February 16, 2023, 12:48pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/7 "2023-02-16T12:48:30Z")

</div>

Doesn’t seem to work.

Passing a pre-defined colormap, `:tab10`, to `boxplot`:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/5/6/5651994e67cc7b568e2ac616e7fa4d0d883655d3.png)

```julia
fig = Figure(backgroundcolor=:grey90)

axs = Axis(fig[1, 1], aspect=AxisAspect(1))

x = Vector{Float64}(undef, 40)

for i = 1:40
    x[i] = i % 4
end 

CairoMakie.boxplot!(axs, x, rand(40); color=map(x -> x % 2 == 0, x), colormap=:tab10)

ylims!(axs, 0, 1)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/2/929a5621282256084c7c932adaa09ccd4cfb2660.png)

Works, but again the first and final colours are plotted.

Passing `colorrange` directly into `boxplot` has no effect except to colour each box the first colour in the colourmap:

```julia
CairoMakie.boxplot!(axs, x, rand(40); color=map(x -> x % 2 == 0, x), colormap=:tab10, colorrange=(1,2)) # expect blue and orange

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/8/980166cefe3bcb16ad7d9b63c3964c2dd4db2d77.png)

Changing the value of `colorrange` to `colorrange=(1,3)`, `colorrange=(2,3)` has no effect.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 16, 2023, 12:57pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/8 "2023-02-16T12:57:42Z")

</div>

You still create color values 0 and 1 (false and true). Either the colorrange needs to then start at 0 or, what I find more straightforward, you start your color categories at 1. Here I’ve extrapolated the approach to multiple groups. `mod1` is a handy function for starting the count at `1`

```julia
fig = Figure(backgroundcolor=:grey90)

n = 200
x = Vector{Float64}(undef, n)

for i = 1:n
    x[i] = mod1(i, 8)
end

colormap = Makie.to_colormap(:tab10)

for (i, k) in enumerate([2, 4, 6, 8])
    ax = Axis(fig[fldmod1(i, 2)...])
    CairoMakie.boxplot!(ax, x, rand(n);
        color=map(x -> mod1(x, k), x), colormap,
        colorrange = (1, length(colormap)))
    ylims!(ax, 0, 1)
end

fig

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/d/1d8e29105ddf2a36e2d7518187463082240ab785.png)

---

<div class="post-metadata">

**Author:** ![jewh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jewh/32/28586_2.png) [@jewh](https://discourse.julialang.org/u/jewh)\
**Post date:** [February 16, 2023, 2:27pm UTC](https://discourse.julialang.org/t/theming-coloured-boxplots-in-makie/94552/9 "2023-02-16T14:27:49Z")

</div>

Excellent, makes sense (and works) now. Thank you for the help.
