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

如何用ggplot绘制总和的中位数线?附现有代码求优化建议

如何用ggplot绘制总和的中位数线(附代码修正)

首先,我先帮你梳理现有代码的问题,然后给出符合需求的解决方案:

核心问题分析

你的代码里有几个关键问题导致无法正常生成想要的图表:

  1. 没有将日期转换为月份分组:你用了aes(Month, n)但数据里根本没有Month列,ggplot会直接报错;
  2. stat_summary的参数过时:fun.y在新版ggplot2中已经被弃用,应该改用fun;
  3. 冗余的日期类型转换:把Date转成POSIXlt没必要,ggplot对原生Date类型支持更好;
  4. 缺少分组设置:如果按月份聚合,需要指定group=1才能让线连续连接。

解决方案:两种常见的"总和中位数线"场景

根据你的描述,我假设你需要两种情况之一,下面分别给出代码:

场景1:每月总计数的线 + 所有月份总计数的中位数水平线

这种场景是先计算每个月的总count,然后添加一条水平线表示所有月份总count的中位数:

library(tidyverse)
library(lubridate)
library(scales)

# 1. 简化日期处理
dataset$Created_Date <- gsub("T.*", "", dataset$Created_Date)
dataset$Created_Date <- ymd(dataset$Created_Date) # 直接用ymd解析,无需strptime

# 2. 重命名列(用dplyr的rename_with更简洁)
dataset <- dataset %>% rename_with(~gsub(" ", "_", .x))

# 3. 统计每日count
dfcount <- dataset %>% count(Created_Date)

# 4. 计算所有月份总count的中位数(先聚合再取中位数)
monthly_totals <- dfcount %>% 
  group_by(month = floor_date(Created_Date, "month")) %>% 
  summarise(total = sum(n)) %>% 
  pull(total)
median_total <- median(monthly_totals)

# 5. 绘制图表
Monthlywithavg <- ggplot(dfcount, aes(x = floor_date(Created_Date, "month"), y = n)) +
  # 按月求和的线(蓝色)
  stat_summary(fun = sum, geom = "line", color = "#1f77b4", size = 1, aes(group = 1)) +
  # 中位数水平线(红色虚线)
  geom_hline(yintercept = median_total, color = "#ff4b5c", linetype = "dashed", size = 1) +
  # x轴格式化:显示年月,每月一个刻度
  scale_x_date(labels = date_format("%Y-%m"), breaks = "1 month") +
  # 图表标签
  labs(x = "Month", y = "Total Daily Count", 
       title = "Monthly Total Count with Overall Median Line") +
  # 美化主题,避免x轴标签重叠
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Monthlywithavg

场景2:每月总计数的线 + 每月内每日count的中位数线

这种场景是同时展示每月的总count,以及每个月内每日count的中位数趋势:

# 沿用前面的数据处理步骤,直接绘制图表
Monthlywithavg <- ggplot(dfcount, aes(x = floor_date(Created_Date, "month"), y = n)) +
  # 按月求和的线(蓝色)
  stat_summary(fun = sum, geom = "line", color = "#1f77b4", size = 1, aes(group = 1)) +
  # 每月内每日count的中位数线(绿色)
  stat_summary(fun = median, geom = "line", color = "#2ca02c", size = 1, aes(group = 1)) +
  scale_x_date(labels = date_format("%Y-%m"), breaks = "1 month") +
  labs(x = "Month", y = "Count", 
       title = "Monthly Total Count vs Daily Median Count",
       caption = "Blue: Monthly Total | Green: Daily Median per Month") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Monthlywithavg

其他需要修改的细节

  1. 日期处理简化:你原来的ymd(strptime(...))可以直接改成ymd(dataset$Created_Date),因为ymd函数能直接识别%Y-%m-%d格式的字符串;
  2. 列重命名优化:用rename_with比直接修改names(dataset)更符合tidyverse风格,也更稳健;
  3. x轴标签可读性:添加theme(axis.text.x = element_text(angle = 45, hjust = 1))可以避免月份标签重叠;
  4. 避免警告:新版ggplot2中fun.y已经被弃用,必须改用fun,否则会弹出警告信息。

内容的提问来源于stack exchange,提问作者Archie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:42:05