You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让直方图时间轴按实际时间而非日期数值排序并显示缺失日期

问题解决: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:46:02