Search code examples
rggplot2widthboxplot

What is causing my ggplot2 boxplot to turn into skinny lines instead of wide boxes using the width argument?


I am struggling with boxplots in R studio. I have a data set that looks like this:

Site date Chloride_mgL
B 2021-06-08 12:00:00 29.13800
D 2021-06-08 12:00:00 29.41100
D 2021-06-15 12:00:00 29.92400
E 2021-06-08 12:00:00 29.29100
A 2021-06-08 12:00:00 29.16800
D 2021-06-22 12:00:00 32.79500
C 2021-06-22 12:00:00 30.59200

Site is characters, date is POSIXct, and Chloride is numeric. I need to make box plots with date on the x axis and Chloride on the y axis, grouped by date. So, for example, I need a box on 2021-06-08 12:00:00 that is made of all of the Chloride values from all of the sites on that date/time. I can get that made, but for some reason when I make it the boxes are tiny and I need them to be bigger, but the width = function just makes the boxes into skinny lines, and not boxes at all.

This is how I make the box plots:

c <- ggplot(sylvan[sylvan$Site %in% c("A", "B", "C", "D", "E", "F", "G") & sylvan$Chloride_mgL > 25, ], aes(x = date, y = Chloride_mgL, group = date)) + 
  geom_boxplot(outlier.shape = NA, color = "dark blue") + theme_minimal() + labs(y ="Chloride (mg/L)")
c

Which gives this:

enter image description here

Great, but I want bigger boxes. So I try to use the width argument:

c <- ggplot(sylvan[sylvan$Site %in% c("A", "B", "C", "D", "E", "F", "G") & sylvan$Chloride_mgL > 25, ], aes(x = date, y = Chloride_mgL, group = date)) + 
  geom_boxplot(width = 2, outlier.shape = NA, color = "dark blue") + theme_minimal() + labs(y ="Chloride (mg/L)")
c

And then it turns into this:

enter image description here

How can I make the boxes wider instead of just turning into skinny little lines? Thanks so much!

Edit: Tried @TarJae solution, and it turned out like this: enter image description here


Solution

  • Here's an example of boxplots with daily data that is in POSIXct:

    set.seed(42)
    df <- data.frame(date = sample(lubridate::ymd_h(c(
      2023040100, 2023050800, 2023051500, 2023051600)), 100, replace = TRUE),
      mgL = rnorm(100, mean = 29))
    

    The default spacing for boxplots on a continuous axis will find a resolution that fits the space.

    ggplot(df, aes(date, mgL, group = date)) +
      geom_boxplot()
    

    enter image description here

    If we specify width = 1, the boxes will be 1 unit wide, which in POSIXct is 1 second, resulting in boxes that are far too narrow.

    ggplot(df, aes(date, mgL, group = date)) +
      geom_boxplot(width = 1)
    

    enter image description here

    Here with 7-day spacing, the first two bars are one week wide, but the last two (which occur one day apart) are squeezed together with narrower bars.

    ggplot(df, aes(date, mgL, group = date)) +
      geom_boxplot(width = 60*60*24*7)
    

    enter image description here

    Or we could convert the x axis to Date, where one unit is a day. With width 1, the last two bars will be lined up with no space between them. Any wider and ggplot will squeeze the overlapping ones to avoid an overlap.

    ggplot(df, aes(as.Date(date), mgL, group = date)) +
      geom_boxplot(width = 1)
    

    enter image description here