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

如何用ggplot绘制年度实例计数柱状图+年度伤亡总和折线图?

解决ggplot中年度实例数柱状图+伤亡总和折线图的匹配问题

问题根源

你遇到的问题核心原因有三个:

  1. x轴类型不匹配:主图层的x是factor(year)(离散型),但折线图用的casualties_by_year里的year是数值型,两者刻度无法对齐,导致折线错位。
  2. 折线分组缺失:离散x轴下,ggplot默认每个x值为单独分组,不指定group=1的话无法将多个点连接成折线。
  3. y轴数值范围差异大:实例数(最大值4)和伤亡总和(最大值41)差距悬殊,单y轴会让折线被压缩到几乎不可见。

修正后的完整代码

我们可以先统一聚合年度统计数据(逻辑更清晰):

# 加载包
library(ggplot2)

# 聚合年度实例数和伤亡总和
instances_by_year <- aggregate(uid ~ year, data = data, FUN = length)
colnames(instances_by_year)[2] <- "instances"
casualties_by_year <- aggregate(casualties ~ year, data = data, FUN = sum)
yearly_data <- merge(instances_by_year, casualties_by_year, by = "year")

# 绘制图表
ggplot(yearly_data, aes(x = factor(year))) +
  # 柱状图:年度实例数
  geom_bar(aes(y = instances), width = 0.4, fill = 'darkorange', stat = "identity") +
  # 折线图:年度伤亡总和,指定group=1确保连线
  geom_line(aes(y = casualties, group = 1), color = "darkblue", size = 1) +
  # 设置双y轴适配数值范围
  scale_y_continuous(
    name = "年度实例数",
    sec.axis = sec_axis(trans = ~ ., name = "年度伤亡总和")
  ) +
  scale_x_discrete(name = "年份") +
  theme_minimal()

如果不想提前聚合实例数,直接用原数据画柱状图的写法:

ggplot() +
  # 原数据直接统计年度实例数
  geom_bar(data = data, aes(x = factor(year)), width = 0.4, fill = 'darkorange') +
  # 折线图用聚合后的伤亡数据,统一x轴类型+指定group=1
  geom_line(data = casualties_by_year, aes(x = factor(year), y = casualties, group = 1), 
            color = "darkblue", size = 1) +
  scale_y_continuous(
    name = "年度实例数",
    sec.axis = sec_axis(~ ., name = "年度伤亡总和")
  ) +
  theme_minimal()

关键修正点解析

  • 统一x轴类型:将折线图的x也设置为factor(year),和柱状图的x轴刻度完全对齐,避免错位。
  • 添加group=1:在geom_line的aes中指定group=1,强制ggplot将所有年份归为同一组,这样才能把离散的点连接成折线。
  • 双y轴适配:通过sec_axis添加第二个y轴,解决两类数据数值范围差距大导致的可视化问题,让折线和柱状图都能清晰展示。
  • stat="identity":当使用提前聚合的实例数数据时,需要指定这个参数,告诉ggplot直接使用我们提供的y值,而不是默认的计数统计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:35:35