4

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.

Ronny Efronny
  • 1,148
  • 9
  • 28

2 Answers2

5

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")
CMichael
  • 1,856
  • 16
  • 20
  • this is great! But in your example there area 7 violins in every column (28 total). I want to give every single violin a different color (total 28 colors) - how would I got about doing THAT? – Ronny Efronny Dec 01 '19 at 12:07
  • 1
    that was just due to the data in my example - there will always be a color for each unique level of the color argument. See my update – CMichael Dec 01 '19 at 12:22
  • This is perfect, I didn't think about mutating. Thank you! – Ronny Efronny Dec 01 '19 at 12:52
2

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

Community
  • 1
  • 1
DJV
  • 4,743
  • 3
  • 19
  • 34
  • would you have a solution if I wanted to have different color schemes for every layer? Like black/white for the firest `geom_violin()` and green/red for the second. Adding a second `scale_fill_manual()` just overrides the first one. – Ronny Efronny Dec 01 '19 at 11:39