I am trying to create a grouped violin plot (see figure), where I am plotting 3 levels for four categorical variables. The plot comes out fine given the data other than the fact that the boxes are the same colour as the wider violin plots behind making them difficult to view. Ideally I would like all the boxes to remain white throughout. I understand that the reason the boxes are changing colour is in response to the fill that I have chosen. I am wondering if there is a way to separate the fill for the geom_violin from the geom_boxplot.
Here is the stripped down code I am using
p <- ggplot(df, aes(x=metric, y=value, fill=variable))+
geom_violin(width=0.9, position=position_dodge(0.75), bw=1.5)+
geom_boxplot(width=0.3, outlier.shape = NA, position=position_dodge(0.75))+
scale_fill_manual(values=c("gray50", "gray75", "gray100"),
breaks=c("res.error.random", "res.error.increase", "res.error.decrease"),
labels=c("random cost", "overestimated", "underestimated"))
1 Answer 1
All depends where you write fill :
- inside
ggplot(aes()): all new layers will be concerned. - inside
geom_boxplot(aes()): only this layer is concerned.
It is important to write it inside aes, especially if you want to use a scale_fill_manual() later.
Here is a full answer with generated data:
df <- data.frame(var1 = sample(c("A", "B", "C"), 50, replace =T),
var2 = sample(c("group1", "group2", "group3"), 50, replace =T),
value = sample(c(1,2,3,4,5,6,7,8,9,10), 50, replace =T))
1.Same color for boxplot and violin [ggplot(aes(fill =))]:
ggplot(df, aes(x=var1, y=value, fill = var2, group = interaction(var1,var2))) +
geom_violin(width=0.9, position=position_dodge(0.75), bw=1.5) +
geom_boxplot(width=0.3, outlier.shape = NA, position=position_dodge(0.75))
2.Different colors [geom_violin(aes(fill =))] :
ggplot(df, aes(x=var1, y=value, group = interaction(var1,var2)))+
geom_violin(width=0.9, position=position_dodge(0.75), bw=1.5, aes(fill = var2))+
geom_boxplot(width=0.3, outlier.shape = NA, position=position_dodge(0.75), fill = "white")
fill = variablein theggplot(aes())and put it in thegeom_boxplot(aes()). In this case, only the boxplot will be concerned by thefillargument