I could manage to construct a line plot as required with ggplot2, but I couldn't replicate the same using ggstatsplot, a package that has many aesthetically pleasing defaults
I am attaching the ggplot2 code, followed by my attempts with ggstatsplot. The main issue is that it is not able to consider interaction as desired, and resorts to faceting
library(dplyr)
library(ggplot2)
library(ggstatsplot)
set.seed(42)
d1 <- data.frame(time_serie = as.factor(rep(rep(1:3, each = 6), 3)),
treatment = as.factor(rep(c("HIGH", "MEDIUM", "LOW"),
each = 18)),
value = runif(54, 1, 10))
d2 <- d1 %>%
summarize(mean_value = mean(value),
sd_value = sd(value),
.by = c(time_serie, treatment))
# Using ggplot2
ggplot(data = d2,
aes(x = time_serie, y = mean_value,
color = treatment, group = treatment)) +
geom_violin(data = d1,
aes(x = time_serie, y = value,
color = treatment, fill = treatment,
group = interaction(treatment, time_serie)),
alpha = 0.1, position = position_dodge(0.3),
inherit.aes = FALSE) +
geom_errorbar(aes(ymin = mean_value - sd_value,
ymax = mean_value + sd_value),
width = .2, position = position_dodge(0.3), linewidth = 1) +
geom_point(position = position_dodge(0.3), size = 3) +
geom_line(aes(color = treatment),
position = position_dodge(0.3), linewidth = 1)
# Using ggstatsplot
#first attempt
grouped_ggwithinstats(data = d1,
x = time_serie, y = value,
grouping.var = treatment)
#second attempt
grouped_ggwithinstats(data = d1,
x = time_serie, y = value,
grouping.var = interaction(treatment, time_serie))
If all you want is to emulate the look of ggstatsplot, you can simply create the same thing inside ggplot using the appropriate geoms, scales and themes. The following is a fully reproducible example using your own sample data set.
library(ggplot2)
set.seed(42)
d1 <- data.frame(time_serie = as.factor(rep(rep(1:3, each = 6), 3)),
treatment = as.factor(rep(c("HIGH", "MEDIUM", "LOW"),
each = 18)),
value = runif(54, 1, 10))
p <- ggplot(d1, aes(time_serie, value,
group = interaction(time_serie, treatment))) +
geom_point(aes(color = treatment, fill = after_scale(alpha(colour, 0.5))),
position = position_jitterdodge(dodge.width = 0.6, 0.1),
size = 3, shape = 21) +
geom_boxplot(fill = NA, color = "black", width = 0.2, linewidth = 0.4,
position = position_dodge(0.6)) +
geom_violin(fill = NA, color = "black", width = 0.6, linewidth = 0.4,
position = position_dodge(0.6)) +
geom_point(stat = "summary", size = 5, color = "#8a0f00",
position = position_dodge(0.6), fun = mean) +
scale_color_brewer(palette = "Set2") +
theme_minimal(base_size = 12) +
theme(axis.title = element_text(face = 2),
legend.position = "bottom",
axis.text.y.right = element_blank())
p
Or if you want the labels too (I think they look a bit messy and obscure the actual data), you can do:
p + geom_label_repel(stat = "summary", fun = mean, size = 3.5,
aes(label = paste0("hat(mu)*scriptstyle(mean)==",
round(after_stat(y), 2))),
parse = TRUE, position = position_dodge(0.6))