eclarke / ggbeeswarm

Column scatter / beeswarm-style plots in ggplot2
GNU General Public License v3.0
539 stars 31 forks source link

Feature Request: Option to vertical jitter? #93

Open mvanaman opened 10 months ago

mvanaman commented 10 months ago
library(psych)
library(ggplot2)
#> 
#> Attaching package: 'ggplot2'
#> The following objects are masked from 'package:psych':
#> 
#>     %+%, alpha
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(tidyr)
library(ggbeeswarm)
set.seed(352)
bfi %>% 
  select(starts_with("O")) %>% 
  pivot_longer(cols = everything(), names_to = "facet", values_to = "rating") %>% 
  slice(sample(1:nrow(.), size = 200)) %>% 
  ggplot(aes(x = facet, y = rating)) +
  geom_beeswarm()

Created on 2023-12-17 with reprex v2.0.2

In use cases such as the above plot, it would be cool to be able to vertically jitter the points slightly to get a sense of the Ns of each rating level. Unless there is a way to do this that I missed!

eclarke commented 5 months ago

Hi @mvanaman, you can do this two ways without using ggbeeswarm . The first is to add jitter manually to the dataframe prior to ggplot- this has the benefit of letting you group the variables with dplyr so the jitter amount is correct. The other way to do it is to simply call jitter() in the aes() argument for your plot, though this ignores any grouping so you'd probably want to manually tune the jitter(amount=...) argument.

Here's an example of both:

library(psych)
library(tidyr)
library(dplyr)

set.seed(352)
dat93 <- bfi %>% 
  select(starts_with("O")) %>% 
  pivot_longer(cols = everything(), names_to = "facet", values_to = "rating") %>% 
  slice(sample(1:nrow(.), size = 200)) %>%
  # "Grouped" jitter
  group_by(facet, factor(rating)) %>%
  mutate(jitter_rating = jitter(rating))

ggplot(dat93, aes(x = facet)) +
  geom_beeswarm(aes(y = jitter_rating, color="grouped jitter"), alpha = 0.5) + 
  # "Within-aesthetic" jitter
  geom_beeswarm(aes(y = jitter(rating), color="within-aesthetic jitter"), alpha = 0.5)

Created on 2024-05-12 with reprex v2.1.0

I personally prefer the first option. I also agree this may be a useful feature to build into ggbeeswarm so I'll keep this open for now.

mvanaman commented 3 months ago

Oh cool, thank you for this solution! (sorry it took so long to acknowledge, I'm grateful you took a look at this)