'jitter according to density

i want to create a combination of violin- and dot-plot with ggplot. The idea is to shift the dots to the left and right if necessary, to avoid overlap.

I know that geom_dotplot does this (left example), but it also groups the dots on the y axis, which I don't want (giving the impression that y is not continuous). geom_jitter also works, but that way it jitters the values independent of the corresponding density.

enter image description here So my ideal plot would be the x position form geom_dotplot but with the true y position. Is there a way to achieve that with ggplot?

library(ggplot2)
data <- data.frame(values=c(rnorm(100, mean = 0),rnorm(100, mean = 1)), typ= c(rep("A",100),rep("B",100)))

ggplot(data, aes(x=typ,y=values))+
  geom_violin()+
  geom_dotplot(binaxis="y",stackdir='center',binwidth = 0.1)

ggplot(data, aes(x=typ,y=values))+
  geom_violin()+
  geom_jitter(width = 0.2)

thank in advance.



Solution 1:[1]

You can use the {ggbeeswarm} package. I'd use ggbeeswarm::geom_quasirandom for this case.

library(ggplot2)
library(ggbeeswarm)

data <- data.frame(values=c(rnorm(100, mean = 0),rnorm(100, mean = 1)), typ= c(rep("A",100),rep("B",100)))

ggplot(data, aes(x=typ,y=values))+
  geom_violin()+
  geom_quasirandom()

Or, as per Richard Telford's comment, ggforce::geom_sina does a similar job. I personally prefer geom_quasirandom because it seems to distribute the points slightly more regularly.

ggplot(data, aes(x=typ,y=values))+
  geom_violin()+
  ggforce::geom_sina()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1