0

I am pretty sure that this is easy to do but I can't seem to find a proper way to query this question into google or stack, so here we are:

I have a plot made in ggplot2 which makes use of geom_jitter(), efficiently creating one row for each element in a factor and plotting its values. I would like to add a complementary geom_violin() to the plot, but just adding the extra geom_ function to the plot code returns two layers: the jitter and the violin, one on top of the other (as usually expected).

EDIT:

This is how the plot looks like: enter image description here How can I have the violin as a separate row, without generating a second plot? Side quest: how I can I have the jitter and the violin geoms interleaved? (i.e. element A jitter row followed by element A violin row, and then element B jitter row followed by element B violin row)

This is the minimum required code to make it (without all the theme() embellishments):

P1 <- ggplot(data=TEST_STACK_SUB, aes(x=E, y=C, col=A)) + 
theme(... , aspect.ratio=0.3) + 
geom_point(position = position_jitter(w = 0.30, h = 0), alpha=0.2, size=0.5) +
geom_violin(data=TEST_STACK_SUB, mapping=aes(x=E, y=C), position="dodge") +
scale_x_discrete() +
scale_y_continuous(limits=c(0,1), breaks=seq(0,1,0.1), 
                  labels=c(seq(0,1,0.1))) + 
scale_color_gradient2(breaks=seq(0,100,20), 
                      limits=c(0,100), 
                      low="green3",
                      high="darkorchid4",
                      midpoint=50,
                      name="") +
coord_flip()

options(repr.plot.width=8, repr.plot.height=2)
plot(P1)

Here is a subset of the data to generate it (for you to try): data

schmat_90
  • 572
  • 3
  • 22
  • 3
    please provide a [minimum reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). Your question can be solved a lot easier with a code which can be modified – mischva11 Jul 01 '19 at 10:06
  • 1
    I'm not sue I understand. Maybe `facet_grid` or `facet_wrap`? – Roland Jul 01 '19 at 10:09
  • FWIW I don't think this is going to be to easy. You might be able to abuse `position_dodge` to do what you want ... – Ben Bolker Jul 01 '19 at 10:44
  • I added a minimum data and code to reproduce it. – schmat_90 Jul 01 '19 at 11:32

1 Answers1

1

How about manipulating your factor as a continuous variable and nudging the entries across the aes() calls like so:

library(dplyr)
library(ggplot2)

set.seed(42)

tibble(x = rep(c(1, 3), each = 10), 
       y = c(rnorm(10, 2), rnorm(10))) -> plot_data

ggplot(plot_data) + 
  geom_jitter(aes(x = x - 0.5, y = y), width = 0.25) + 
  geom_violin(aes(x = x + 0.5, y = y, group = x), width = 0.5) + 
  coord_flip() + 
  labs(x = "x") + 
  scale_x_continuous(breaks = c(1, 3), 
                     labels = paste("Level", 1:2), 
                     trans = scales::reverse_trans())

plot output

the-mad-statter
  • 5,650
  • 1
  • 10
  • 20
  • 1
    I'm not sure the copied data is strictly necessary. I get similar results by adding +/- 0.4 to the x mapping of the two layers using a single copy of the data, e.g. `ggplot() + geom_jitter(aes(x = x, y = y), data = tbl.jit, width = 0.25) + geom_violin(aes(x = x, y = y, group = x), data = tbl.vio, width = 0.5) + ...` – Jon Spring Jul 01 '19 at 12:23
  • 1
    Ah yes, great idea! – the-mad-statter Jul 01 '19 at 12:27
  • 1
    Oops pasted wrong above, meant `x = x - 0.4` and `x = x + 0.4` for the two aes calls. – Jon Spring Jul 01 '19 at 12:29