Overlay scatterpoints on split violin plot with gg

2019-07-23 10:23发布

I followed this nice answer to generate split violin plots in a 2x2 design

Now imagine that these data come from repeated measures in different subjects. I'd like to, additionally, plot the individual data in a scatterplot (I know the plot might end up being too busy, I'd like to see it first).

I'm almost there, but have a small error that's probably easily fixed. I include a whole working example in case there's a better way to do this.

This first part I copied directly from the previous question:

library(dplyr)
library(ggplot2)

set.seed(20160229)

I added subj to my dataframe because I'll want to plot each subject's mean

my_data = data.frame(
  y=c(rnorm(1000), rnorm(1000, 0.5), rnorm(1000, 1), rnorm(1000, 1.5)),
  x=c(rep('a', 2000), rep('b', 2000)),
  m=c(rep('i', 1000), rep('j', 2000), rep('i', 1000)),
  subj=c(rep(c(rep('1',200),rep('2',200),rep('3',200),rep('4',200),rep('5',200)),4))
)

pdat <- my_data %>%
  group_by(x, m) %>%
  do(data.frame(loc = density(.$y)$x,
                dens = density(.$y)$y))

pdat$dens <- ifelse(pdat$m == 'i', pdat$dens * -1, pdat$dens)
pdat$dens <- ifelse(pdat$x == 'b', pdat$dens + 1, pdat$dens)


ggplot(pdat, aes(dens, loc, fill = m, group = interaction(m, x))) + 
  geom_polygon() +
  scale_x_continuous(breaks = 0:1, labels = c('a', 'b')) +
  ylab('density') +
  theme_minimal() +
  theme(axis.title.x = element_blank())

So far, works great. Now I try to add my mean values for each subject

meanY = aggregate(y ~ x + m + subj, my_data, mean, drop=TRUE)


ggplot(pdat, aes(dens, loc, fill = m, group = interaction(m, x))) + 
  geom_polygon() +
  geom_point(data=meanY, aes(fill = m, group = interaction(m, x))) +
  scale_x_continuous(breaks = 0:1, labels = c('a', 'b')) +
  ylab('density') +
  theme_minimal()

I get the error: Error in eval(expr, envir, enclos) : object 'dens' not found

1条回答
贪生不怕死
2楼-- · 2019-07-23 10:53

If I understood correctly you need to specify x and y in geom_point:

ggplot(pdat, aes(dens, loc, fill = m, group = interaction(m, x))) + 
  geom_polygon() +
  scale_x_continuous(breaks = 0:1, labels = c('a', 'b')) +
  ylab('density') +
  theme_minimal() +
  theme(axis.title.x = element_blank()) +
  geom_point(data = meanY, aes(x = ifelse(x == "a", 0, 1), y = y, fill = m, group = interaction(m, x)), shape = 21, colour = "black", show.legend = FALSE)

enter image description here

查看更多
登录 后发表回答