使用ggplot2创建甘特图:scale_x_date函数可以将日期显示为季度例如,2020年第四季度吗?

问题描述

我正在使用ggplot2准备甘特图。我找到了一种最有用的方法,但是我想进一步改善输出

以下示例代码创建一个数据框(之所以这样设置是因为它相对容易进行动态编辑):

df <- as.data.frame(rbind(
    c("Category_1","task_1",'2020-10-01','2020-12-31'),c("Category_1","task_2",'2021-01-01','2021-04-01'),c("Category_2","task_3",'2021-06-15','2021-10-01'))) %>%
  select("Category" = 1,"task" = 2,"start" = 3,"end" = 4) %>%
  mutate(Category = (factor(Category,levels = (unique(Category)))),task = fct_rev(factor(task,levels = (task))),start = as.Date(start),end = as.Date(end)) %>%
  mutate(lab_pos = start) %>%
  pivot_longer(3:4,names_to = "variable",values_to = "value")

然后此代码创建甘特图(简化了共享):

ggplot(df,aes(value,task,color = Category)) + 
  geom_line(size = 14,show.legend = FALSE) +
  scale_x_date(date_labels = " %y %b",limits = c(as.Date('2020-06-30'),as.Date('2021-12-31')),date_breaks = '3 months',date_minor_breaks = "1 month",position = "top") +
  labs(x = NULLy = NULL) +
  facet_grid(Category ~ .,space = "free_y",scales = "free_y",switch = "both")  

所以问题是如何显示scale_x_date生成的x轴单位而不是日期?例如,不是1月21日,我更喜欢Q1 21。比scale_x_date更好的方法

第二个问题是:如果我可以得到四分之一标签,可以将其移动到四分之一的中间,以便主要网格线与四分之一相邻,标签位于它们之间,从而将整个区域标识为一季度?

解决方法

我们可以使用labels而不是date_labels参数,并传递自定义函数以从日期中提取季度信息。

library(ggplot2)

ggplot(df,aes(value,task,color = Category)) + 
  geom_line(size = 14,show.legend = FALSE) +
  scale_x_date(labels =  function(x) paste(quarters(x),format(x,'%Y')),limits = c(as.Date('2020-06-30'),as.Date('2021-12-31')),date_breaks = '3 months',date_minor_breaks = "1 month",position = "top") +
  labs(x = NULL,y = NULL) +
  facet_grid(Category ~ .,space = "free_y",scales = "free_y",switch = "both")

enter image description here