1

How can I add some padding between the various point groups (so that they are not all staying in the same vertical line)? To separate the point more like this other plot (figure 2). (The geom_jitter is not the solution, as it spreads the points all over)

Is there anything similar to position_dodge2() option?

Here I provide a test dataset

dataset <- data.frame(drug = rep(c("drug 1", "drug 2", "drug 3", "drug 4", "drug 5"), 20),
                      mouse =rep(paste0("test", 1:2), 50),
                      color = rep(c("color1", "color2", "color3", "color4"), 25),
                      amount_color = runif(100, 1, 2)
)


dataset %>% 
  ggplot(aes(x = drug, y = amount_color, col = mouse)) +
  stat_sum() +
  theme_light() +
  theme(axis.text.x = element_text(angle = 45, hjust=1)) +
  stat_summary(fun="mean", geom="segment", mapping=aes(xend=..x.. - 0.5, yend=..y..), size = 1.5) +
  stat_summary(fun="mean", geom="segment", mapping=aes(xend=..x.. + 0.5, yend=..y..), size = 1.5)

Thank you very much.

enter image description here enter image description here

flavinsky
  • 309
  • 4
  • 13

1 Answers1

1

Here's a bizarrely complicated way to get what you want. The first part makes up a dataset with column count in it; I'm using that to control the number of points. You'll want something different for stat_sum(), but I can't figure out what your dataset looks like.

df <- data.frame(group = sample(LETTERS[1:2], 10, replace=TRUE), y = rnorm(10), count = 1+ rbinom(10, 20, 0.2))


library(ggplot2)
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

p <- ggplot(df %>% filter(count %% 2 == 1), aes(x=group, y=y))

spacing <- 0.03
for (i in 1:max(df$count)) {
  # First the even counts
  nudge <- ((i+1) %/% 2 - 0.5)*spacing
  if (i %% 2 == 1) nudge <- -nudge
  df0 <- df %>% filter(count %% 2 == 0 & count >= i)
  p <- p + geom_point(data = df0, 
                      position = position_nudge(x = nudge))
  # Now the odd counts
  nudge <- (i %/% 2)*spacing
  if (i %% 2 == 1) nudge <- -nudge
  p <- p + geom_point(data = df %>% filter(count %% 2 == 1 & count >= i), 
                      position = position_nudge(x = nudge))
}
p

Created on 2021-09-16 by the reprex package (v2.0.0)

This is one of the disadvantages of ggplot2. If you want to do something new and can't find a function that someone else has written to it, it's really hard. Hopefully someone has already written a function to do this and will point it out now.

user2554330
  • 37,248
  • 4
  • 43
  • 90
  • I added a reproducible example of my dataset @user2554330. Thank you for your answer. Do you think your solution could be implemented in my dataset with `stat_sum()`? – flavinsky Sep 17 '21 at 09:05
  • Now I can't see what grouping you want -- all your points are `n=1` in your example. – user2554330 Sep 17 '21 at 10:47
  • I would like drug1 to have both test 1 and test 2 information but a bit separated, so that it does not plot so messy (basically the blue and the red separated horizontally and so that the points are not laying within the same vertical line) – flavinsky Sep 17 '21 at 11:26
  • I would recommend using `geom_dotplot` or `ggbeeswarm::geom_beeswarm`instead of trying to invent your own. – Ian Campbell Sep 19 '21 at 14:57