Reputation: 311
I am trying to create a box plot with labels for some of the individal data. The box plot is separated by two variables, mapped to x and colour. However when I add labels using geom_text_repel from the ggrepel package (necessary for the real data) they separate by x but not colour. See this minimal reproducible example:
library(ggplot2)
library(ggrepel)
## create dummy data frame
rep_id <- c("a", "a", "b", "b", "c", "c", "d", "d", "e", "e")
dil <- c(1, 1, 1, 1, 2, 2, 2, 2, 2, 2)
bleach_time <- c(0, 24, 0, 24, 0, 24, 0, 24, 0, 24)
a_i <- c(0.1, 0.2, 0.35, 0.2, 0.01, 0.4, 0.23, 0.1, 0.2, 0.5)
iex <- data_frame(rep_id, dil, bleach_time, a_i)
rm(rep_id, dil, bleach_time, a_i)
## Plot bar chart of a_i separated by bleach_time and dil
p <- ggplot(iex, aes(x = as.character(bleach_time), y = a_i, fill = as.factor(dil))) +
geom_boxplot() +
geom_text_repel(aes(label = rep_id, colour = as.factor(dil)), na.rm = TRUE, segment.alpha = 0)
p
As you can see the labels are colour coded, but they are all lined up around the centre of each pair of plots rather than separated by the plots. I've tried nudge_x but that moves all the labels together. Is there a way I can move each set of labels individually?
For comparison here is the plot of my full data set with the outliers labelled - you can see how each set of labels isn't centred around the points it's labelling, complicating interpretation:
Upvotes: 2
Views: 1432
Reputation: 16862
It looks like geom_text_repel
needs position = position_dodge(width = __)
, not just the position = "dodge"
shorthand I'd suggested, hence the error. You can mess around with setting the width; 0.7 looked okay to me.
library(tidyverse)
library(ggrepel)
ggplot(iex, aes(x = as.character(bleach_time), y = a_i, fill = as.factor(dil))) +
geom_boxplot() +
geom_text_repel(aes(label = rep_id, colour = as.factor(dil)), na.rm = TRUE,
segment.alpha = 0, position = position_dodge(width = 0.7))
Since you're plotting distributions, it might be important to keep positions along the y-axis the same, and only let geom_text_repel
jitter along the x-axis, so I repeated the plot with direction = "x"
, which made me notice something interesting...
ggplot(iex, aes(x = as.character(bleach_time), y = a_i, fill = as.factor(dil))) +
geom_boxplot() +
geom_text_repel(aes(label = rep_id, colour = as.factor(dil)), na.rm = TRUE,
segment.alpha = 0, position = position_dodge(width = 0.7), direction = "x")
There are a couple texts being obscured by the fact that they have the same color as the fill of the boxplots! You can fix this with a better combination of color + fill palettes. The quick fix I did was turning down the luminosity of the color and turning up the luminosity of the fill in the scale_*_discrete
calls to make them distinct (but also pretty ugly).
ggplot(iex, aes(x = as.character(bleach_time), y = a_i, fill = as.factor(dil))) +
geom_boxplot() +
geom_text_repel(aes(label = rep_id, colour = as.factor(dil)), na.rm = TRUE,
segment.alpha = 0, position = position_dodge(width = 0.7), direction = "x") +
scale_color_discrete(l = 30) +
scale_fill_discrete(l = 100)
Note that you can also adjust the force used in the repel, so if you need the labels to not overlap but to also hug closer to the middles of the boxplots, you can mess around with that setting as well.
Upvotes: 1