Jadabu - 9 months ago 154

R Question

I have plotted grouped boxplots and now I would like to replace the standard black median line with a white line while keeping the borders in an other color. I'm following the instructions on the site Minimalist Boxplots because I really like their style.

They use the command

`stat_summary(geom = "crossbar", width=0.65, fatten=0, color="white", fun.data = function(x){ return(c(y=median(x), ymin=median(x), ymax=median(x))) })`

That command worked well with simple boxplots:

But now that I'm trying to use it on my grouped boxplots its not working anymore (white median line is missing):

Here is my the code for reproducing my data:

`Data <- data.frame(`

W = sample(1:100),

M = sample(1:100),

A = sample(1:100),

O = sample(1:100),

Type = sample(c("1", "2", "3", "4", "5")))

And my script:

`Data_Boxplot <- melt(Data,id.vars='Type', measure.vars=c('W','M','A', 'O'))`

Boxplots <- ggplot(Data_Boxplot, aes(Type, value, group=variable)) +

geom_boxplot(outlier.colour = NULL, aes(color=variable, fill=variable)) +

stat_summary(geom = "crossbar", width=0.65, fatten=0, color="white",

fun.data = function(x){c(y=median(x), ymin=median(x), ymax=median(x))})

Boxplots

What do I have to change? Thank you very much for your help.

Answer

You only mapped `x`

and `y`

for the `geom_boxplot`

. Variables that are shared among geoms should be mapped for all. In this case, you also need to group by `variable`

.

```
ggplot(Data.m, aes(Type, value, group=variable) +
geom_boxplot(outlier.colour = NULL, aes(color=variable, fill=variable)) +
stat_summary(geom = "crossbar", width=0.65, fatten=0, color="white",
fun.data = function(x){c(y=median(x), ymin=median(x), ymax=median(x))})
```

I did not test, as you did not provide data.

Ok, now that we have a good example with data we can see what's going on.

There is actually a two issues I had missed. Both are because `geom_boxplot`

will automatically solve some problems for you because of the `fill`

, that `stat_summary`

doesn't. So we'll have to do them manually.

Firstly, we want to be grouping on both `variable`

as well as `Type`

, we can do this by using the `interaction`

function.

Secondly, the boxplots are automatically dodged (i.e. moved apart within groups), while the horizontal lines aren't. We'll define our positioning using `position_dodge`

, and apply it to both geoms. Applying it to both is the easiest way to make them exactly line up. We end up with:

```
p <- position_dodge(0.8)
ggplot(Data_Boxplot, aes(Type, value, group = interaction(variable, Type))) +
geom_boxplot(aes(color = variable, fill = variable), outlier.colour = NULL, position = p) +
stat_summary(geom = "crossbar", width = 0.6, fatten=0, color="white", position = p,
fun.data = function(x){c(y=median(x), ymin=median(x), ymax=median(x))}) +
theme_minimal()
```

Source (Stackoverflow)