使用scale_x_datetime和geom_col移动x轴刻度线,以使条形图不会以刻度线为中心

问题描述

我正在使用半小时间隔绘制时间序列数据,使用geom_col()来显示每个间隔中计数的鸟类数量。 ggplot2在x轴刻度上绘制每个居中的居中,但是我需要每个条形码开始到每个刻度的 向右 。换句话说,我需要每个条形图跨越其相应的半小时间隔的宽度。

我没有运气就尝试过这些帖子中建议的解决方案:

下面是重现该问题的示例代码

    ``` r
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date,intersect,setdiff,union
library(ggplot2)
library(tidyverse)

df <- data.frame(
  date = c("2019-05-16","2019-05-16","2019-05-16"),time = c("16:30:00","17:00:00","17:30:00","18:00:00","18:30:00","19:00:00","19:30:00","20:00:00"),count = c(5,100,14,342,59,321,44,98),stringsAsFactors = FALSE)

datetime_df <- df %>% 
  mutate(time_stamp = paste(date,time) %>% as_datetime())

plot <- ggplot(datetime_df,aes(x = time_stamp,y = count)) +
  geom_col() +
  scale_x_datetime(breaks = scales::date_breaks("30 mins"),date_labels = "%H:%M",limits = c(as_datetime("2019-05-16 16:00:00"),as_datetime("2019-05-16 20:30:00"))) +
  scale_y_continuous(expand = c(0,0),breaks = seq(0,500,by = 50),limits = c(0,500))

reprex package(v0.3.0)于2020-10-01创建

Here is the resulting bar chart

非常感谢您提供有关解决此问题的想法!

解决方法

您可以通过增加15分钟的时间来轻松模拟这一点:

plot <- ggplot(datetime_df,aes(x = time_stamp + minutes(15),y = count)) +
  geom_col() +
  scale_x_datetime(breaks = scales::date_breaks("30 mins"),date_labels = "%H:%M",limits = c(as_datetime("2019-05-16 16:00:00"),as_datetime("2019-05-16 20:30:00"))) +
  scale_y_continuous(expand = c(0,0),breaks = seq(0,500,by = 50),limits = c(0,500))
plot

enter image description here

要使刻度线与小节的开头完全对齐,您需要在width中设置geom_col参数以匹配添加的分钟数。经过一番尝试和错误后,这似乎可行:

half_width_in_min = 13
plot <- ggplot(datetime_df,aes(x = time_stamp + minutes(half_width_in_min ),y = count)) +
  geom_col(width = 60 * 24 * 1.25 * half_width_in_min / 15) +
  scale_x_datetime(breaks = scales::date_breaks("30 mins"),500))
plot

enter image description here