This is driving me up the wall, and I'm sure I am missing something simple. Any help would be appreciated.
I want the red and blue points to be separated, with each set over the corresponding boxplot as in second image, but with a numeric x axis as in the first image.
df <- data.frame(x = rep(c(1, 2, 10), each = 20),
g = rep(c("A", "B"), times = 30),
y = c(rnorm(60, 0, 1)))
# OK - boxplot by x and g
ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
geom_boxplot()
# Not OK. The dots are only grouped by x, not g
ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
geom_point()
# I want the points to correctly overlay the boxplots
ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
geom_boxplot(alpha = 0.1) +
geom_point()
(I have fixed it by faceting on x, but I want the axis as numeric to reflect the correct scaling)
ggplot(df, aes(y = y, x = g, fill = g, color = g, group = interaction(x, g))) +
geom_boxplot(alpha = 0.1) +
geom_point() +
facet_wrap(~x)
You can use position=position_dodge(...)
in geom_point
.
ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
geom_boxplot(alpha = 0.1, width=0.75) +
geom_point(position = position_dodge(width=0.75))
I also defined a width for geom_boxplot
to match the position_dodge
width in geom_point
.
In case you want jitter as well, you can use position_jitterdodge
.
ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
geom_boxplot(alpha = 0.1, width=0.75) +
geom_point(position = position_jitterdodge(jitter.width=0.85))
If using geom_beeswarm
, you can use the dodge.width
option
library(ggbeeswarm)
ggplot(df, aes(y = y, x = x, fill = g, color = g, group = interaction(x, g))) +
geom_boxplot(alpha = 0.1, width = 0.75) +
geom_beeswarm(dodge.width = 0.75)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With