如何让直方图时间轴按实际时间而非日期数值排序并显示缺失日期
问题解决:ggplot2日期轴排序与缺失日期间隔显示
核心问题
Date_obs列以字符串格式存储,ggplot按字符串字典序排序,导致5月的日期(26/05/2021、27/05/2021)排在6月日期之后- 图表无法体现缺失日期的间隔(如6月16日到18日之间的空白)
完整调整代码
library(ggplot2) library(dplyr) library(tidyverse) library(lubridate) # 用于日期格式转换 # 原始数据 cd<-structure(list(Bloc = c(7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7), Pos_heliaphen = c("W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17", "W16", "W17"), traitement = c("WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW", "WS", "WW"), Variete = c("Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas"), Date_obs = c("26/05/2021", "26/05/2021", "27/05/2021", "27/05/2021", "04/06/2021", "04/06/2021", "07/06/2021", "07/06/2021", "08/06/2021", "08/06/2021", "11/06/2021", "11/06/2021", "14/06/2021", "14/06/2021", "15/06/2021", "15/06/2021", "16/06/2021", "16/06/2021", "18/06/2021", "18/06/2021", "21/06/2021", "21/06/2021", "23/06/2021", "23/06/2021", "25/06/2021", "25/06/2021", "28/06/2021", "28/06/2021", "29/06/2021", "29/06/2021"), SF_tot = c(NA, NA, 43990.8, 44589.3, NA, NA, 139515.6, 147384.3, NA, NA, 187836.6, 198513, 234408.3, 249490.5, NA, NA, 256949.7, 296826.6, 260007.3, 337029, 260007.3, 389098.5, 260007.3, 418418.7, 260007.3, 446741.4, 260007.3, 446741.4, 260007.3, 446741.4)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -30L)) # 数据预处理 df <- subset(cd, Variete %in% c("Blancas")) options(scipen=200) df <- df %>% select(1:6) %>% pivot_longer(starts_with("SF")) %>% # 将字符串日期转换为日期类型,解决排序问题 mutate(Date_obs = dmy(Date_obs)) df2 <- df %>% group_by(Bloc, Date_obs) %>% summarize(ww = paste0(Pos_heliaphen, collapse = "-"), .groups = "drop") # 生成完整日期序列,补全缺失日期以显示间隔 full_dates <- tibble(Date_obs = seq(min(df$Date_obs), max(df$Date_obs), by = "day")) full_data <- expand_grid( Date_obs = full_dates$Date_obs, traitement = unique(df$traitement), Bloc = unique(df$Bloc), Pos_heliaphen = unique(df$Pos_heliaphen), Variete = unique(df$Variete) ) %>% left_join(df, by = c("Date_obs", "traitement", "Bloc", "Pos_heliaphen", "Variete")) %>% left_join(df2, by = c("Bloc", "Date_obs")) # 绘制调整后的图表 full_data %>% ggplot(aes(Date_obs, value, group=traitement, fill = traitement)) + geom_bar(stat = "identity", position = "dodge", na.rm = TRUE) + scale_fill_manual(values = c("#8FBC94","#548687"))+ # 设置x轴为日期刻度,自定义显示格式 scale_x_date(date_labels = "%d/%m/%Y", breaks = full_dates$Date_obs) + facet_wrap(~ww, drop=TRUE)+ labs(y=expression(paste('Original total leaf area (mm'^2,')')))+ theme( legend.position="bottom", axis.text.x = element_text(angle = 90, hjust = 1), axis.title.x = element_blank() ) + labs(title = "Blancas")
关键调整说明
- 日期格式转换:使用
lubridate::dmy()将Date_obs从字符串转为日期类型,让ggplot自动按时间顺序排序,解决5月日期后置问题 - 补全缺失日期:通过
seq()生成覆盖所有日期的序列,结合expand_grid创建所有变量组合,左连接原数据后,缺失日期对应的值为NA,图表中会自动显示空白间隔 - 日期轴自定义:
scale_x_date()设置日期显示格式为%d/%m/%Y(日/月/年),并使用完整日期序列作为刻度,确保所有日期逻辑都被展示
内容的提问来源于stack exchange,提问作者Chouette
相关产品推荐
相关产品推荐

