Home > database >  setting limits with scale_x_datetime() silently drops bar in ggplot
setting limits with scale_x_datetime() silently drops bar in ggplot

Time:10-08

Primary goal: I am trying to build a series of bar plots from different tibbles with one set of x and y limits and scales for ease of comparison across plots. The x-axis is datetime and the y-axis is numeric. I'm using the most inclusive x and y ranges from the set of tibbles to define the limits and scales for all the plots.

Challenge: When I add limits to scale_x_datetime() to set the x-axis range, ggplot silently drops the data I am trying to plot, even though the x value for my data is within the limits. The code below shows an example from a single plot, as well as a few things I tried (unsuccessfully) to get the bar to show up when using the limits argument of scale_x_datetime().

library(dplyr)
library(tibble)
library(ggplot2)
library(lubridate)

example_dat <- tibble(
  author_name = 'fname lname', 
  time_window = as_datetime('2019-12-07 00:00:00'),
  time_read = 32.4
)

lims <- c(as_datetime('2019-12-01 00:00:00'), 
         as_datetime('2019-12-09 00:00:00'))

# when I plot without limits, the bar appears as expected
example_dat %>%
  ggplot(aes(x = time_window, y = time_read))   
  geom_bar(stat = 'identity')  
  scale_x_datetime()  
  ylim(0, 35) 

# when I plot with limits, the bar is silently dropped
example_dat %>%
  ggplot(aes(x = time_window, y = time_read))   
  geom_bar(stat = 'identity')  
  scale_x_datetime(limits = lims)  
  ylim(0, 35) 

# specifying breaks alongside the limits does not help, the bar is still silently dropped
example_dat %>%
  ggplot(aes(x = time_window, y = time_read))   
  geom_bar(stat = 'identity')  
  scale_x_datetime(limits = lims, breaks = as_datetime(c('2019-12-01 00:00:00', 
                                                         '2019-12-02 00:00:00', 
                                                         '2019-12-03 00:00:00', 
                                                         '2019-12-04 00:00:00',
                                                         '2019-12-05 00:00:00', 
                                                         '2019-12-06 00:00:00',
                                                         '2019-12-07 00:00:00', 
                                                         '2019-12-08 00:00:00', 
                                                         '2019-12-09 00:00:00')))  
  theme(axis.text.x = element_text(angle = 90))  
  ylim(0, 35)

# using as.POSIXct() instead of as_datetime() to define the limits does not help, the bar is still silently dropped
p_lims <- as.POSIXct(c('2019-12-01 00:00:00', '2019-12-09 00:00:00'), 
                     tz = "GMT")

example_dat %>%
  ggplot(aes(x = time_window, y = time_read))   
  geom_bar(stat = 'identity')  
  scale_x_datetime(limits = p_lims)  
  ylim(0, 35)  

With no error messages, I suspect this is a gap in my understanding of the way scales and dates interact in ggplot. Any insights here would be much appreciated.

Session context:

R version 4.1.0 (2021-05-18)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 11.5.2

attached base packages:
[1] stats     graphics  grDevices utils     datasets 
[6] methods   base     

other attached packages:
[1] lubridate_1.7.10 ggplot2_3.3.5    scales_1.1.1    
[4] tibble_3.1.5     dplyr_1.0.7     

Thanks

CodePudding user response:

It's there, it's just veeeeeeeery narrow!

I think in this case ggplot is interpreting your example as occurring during 1 second, since that's the resolution of your data, but your time range is 8 days x 24 hours x 60 m x 60 s = 691,200 seconds long.

To make the bar "one day" wide:

example_dat %>%
  ggplot(aes(x = time_window, y = time_read))   
  geom_bar(stat = 'identity', width = 60*60*24)  
  scale_x_datetime(limits = lims)  
  ylim(0, 35) 

enter image description here

  • Related