0

I am making a boxplot where each categorical variable on the x-axis has 2 corresponding box plots (side-by-side). I am trying to label the median bar, but the labels come out stacked rather than side by side -- image below for reference.

How can I move the top label to the left and the bottom label to the right along the x-axis? My code is below, I've tried a wide variety of position nudges and v values with no success.

 ggplot() + 
   geom_boxplot(data = data, aes(x = cat_var, y = value, fill=status), alpha = 0.3) +
   scale_y_log10() +
   facet_wrap(~cat_var2) +
   scale_fill_manual(values=cat.colors) +
   geom_text(data = labs2, aes(x = cat_var, y = med, label = med), position = 
   position_nudge(x=0.05, y=.05))

enter image description here

0

1 Answer 1

0

You need to use the same position as geom_boxplot, which by default is position_dodge2. You don't need a separate labels data frame; you can use stat = "summary" inside geom_text to get the label positions:

ggplot(data, aes(x = cat_var, y = value, fill = status)) + 
  geom_boxplot(alpha = 0.3) +
  geom_text(stat = "summary", fun = "median", vjust = -0.5,
            position = position_dodge2(width = 0.8),
            aes(label = round(after_stat(y)))) +
  scale_y_log10() +
  facet_wrap(~cat_var2) +
  scale_fill_manual(values = cat.colors) 

enter image description here


Data used

It took more work to create a data set with the same structure as your own as it did to answer the question. Please try to make questions reproducible. The data set used in the plot above was created as follows:

library(tidyverse)

set.seed(1)

data <- expand.grid(cat_var = factor(c("Less than 3km away", 
                                       "3 - 5km away",
                                        "More than 5km away"),
                                     c("Less than 3km away", 
                                       "3 - 5km away",
                                       "More than 5km away")),
                    cat_var2 = c("High", "Moderate", "None"),
                    status = c("Impact Sector", "Non-Impact Sector")) %>%
  group_by(across(everything())) %>%
  reframe(value = rgamma(100, 3, 1e-4) + 1000)

cat.colors <- c("dodgerblue", "limegreen")
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.