Search code examples
rggplot2boxplot

R: Doge boxplot when using factor() on x axis


I want to dodge a simple boxplot so I can see two different measures at once, which should be rather simple but I have been super stuck.

This is what I want

For each intensity of "strength" I want to plot two different boxes next to each other, one for the True Postives and one for the False Positives.

This is the mess I have:

ggplot(data, aes(x = factor(strength))) +
  geom_boxplot(aes(y = TP, fill = "TP"), position = position_dodge(width = 0.8)) +
  geom_boxplot(aes(y = FP, fill = "FP"), position = position_dodge(width = 0.8)) +
  scale_fill_manual(values = c("TP" = "blue", "FP" = "red")) +
  labs(title = "Count",
       x = "Strength", y = "Count")

I am probably overlooking something, but why is position_dodge() not doing its job?

And here is a small example of what my data looks like:


# trial   strength     FP  TP
# 1       -3           5   6
# 1       2            6   7
# 1       1            2   1
# 2       -2           3   4
# 2       2            4   4
# 2       3            2   2


Solution

  • As already noted in the comments to make position_dodge work you have to reshape your data to long or tidy format using e.g. tidyr::pivot_longer.

    Using some fake random example data:;

    library(ggplot2)
    library(tidyr)
    
    set.seed(123)
    
    data <- data.frame(
      strength = rep(c(-3:-1, 1:3), each = 10),
      FP = sample(1:10, 60, replace = TRUE),
      TP = sample(1:10, 60, replace = TRUE)
    )
    
    data |>
      pivot_longer(c(FP, TP), names_to = "name", values_to = "value") |>
      ggplot(aes(factor(strength), value, fill = name)) +
      geom_boxplot(position = position_dodge(width = 0.8)) +
      scale_fill_manual(values = c("TP" = "blue", "FP" = "red")) +
      labs(
        title = "Count",
        x = "Strength", y = "Count"
      )
    

    plot