Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create multiple stacked violin plots with ggplot

I have a model which runs on different landscapes, once on both together and once on each separately. I would like to plot the results in violin plots, but I'd like to have both runs side by side in the same plot, and each landscape to have its own violin (so a collective 4 violins in 2 stacks). Example data:

df1 <- data.frame('means' = 1:6, 'landscape' = rep(c('forest', 'desert', 3)))
df2 <- data.frame('means' = rep(c(1,2), 3), 'landscape' = rep(c('forest', 'desert', 3)))

How I'd like the final product to look like (illustration in MS Paint and I'm a terrible artist): enter image description here

where green is for forests and gold is got deserts.

like image 843
Ronny Efronny Avatar asked Mar 03 '23 02:03

Ronny Efronny


2 Answers

Note that this post implictly asks "how to have violin geoms printed above each other?". This is of course answered through the position argument which for violins defaults to 'dodge' - changing it to 'identity' does the trick. Little side remark - asking for "stacking" is actually somewhat misleading as position='stack' will vertically stack them.

This approach in particular avoids the clunky second data set and hence easily works with multiple colors.

library(tidyverse)

mpg %>%
  filter(class %in% c("compact","midsize")) %>%
  mutate(coloringArgument = paste(drv,class)) %>%
  ggplot(aes(as.factor(drv), cty, color=coloringArgument)) + 
  geom_violin(position = "identity")
like image 62
CMichael Avatar answered Mar 21 '23 05:03

CMichael


Using ggplot - you can add two geom_violin() and in the second one, use new data.

I used mtcars as sample data.

library(tidyverse)

df1 <- mtcars[1:15, ]
df2 <- mtcars[16:31, ]

df1 %>% 
  ggplot(aes(factor(vs), disp)) + 
  geom_violin() + 
  geom_violin(data = df2, 
              aes(factor(vs), disp))

enter image description here

EDIT

If possible, I think that the easier way would be to combine the data frames, into one and create a key for each of one them for later use. To combine the data.frames I used bind_rows which binds the data.frames on top of the others. The argument .id = enables me to add a new column with the data.frame's name. Next, inside ggplot you can set the aes color to the data.frame id you gave. This will give different colord for each data.frame. In addition, adding position = "identity" inside geom_violin lets you stack them over each other.

bind_rows(list(df1 = df1, df2 = df2),
          .id = "dfName") %>% 
  ggplot(aes(factor(vs), disp, color = dfName)) + 
  geom_violin(position = "identity")

enter image description here

like image 30
DJV Avatar answered Mar 21 '23 05:03

DJV