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

如何在R直方图中添加基于tonne.km权重的累积趋势线并调整双轴?

解决方案:带加权累积趋势线的直方图调整

不需要更换图表类型,通过正确使用weight参数和ggplot的统计变量,就能实现主轴显示区间tonne.km总和、次轴显示加权累积占比的需求。

直接在ggplot中实现(推荐)

利用ggplot的内部统计变量..sum..(对应weight参数的区间总和),直接生成直方图和累积曲线:

library(tidyverse)
library(scales)

# 测试数据
distance <- rnorm(1000000, mean = 1000, sd = 500)
tonne.km <- rnorm(1000000, mean = 25000, sd = 500)
dist.tk.test <- tibble(distance, tonne.km)

# 修正后的绘图代码
dist.tk.test %>% 
  ggplot() +
  # 直方图:每个柱子高度为对应区间的tonne.km总和
  geom_histogram(
    aes(x = distance, y = ..sum.., weight = tonne.km),
    bins = 50, fill = "lightblue", alpha = 0.7
  ) +
  # 累积趋势线:基于tonne.km的加权累积占比
  stat_bin(
    aes(x = distance, y = cumsum(..sum..) / sum(..sum..), group = 1),
    geom = "line", color = "red", size = 1, weight = tonne.km
  ) +
  # x轴格式化
  scale_x_continuous(label = comma, breaks = extended_breaks(10)) +
  # 双y轴设置
  scale_y_continuous(
    name = "Tonne.km 总和",
    labels = comma,
    sec.axis = sec_axis(~ ., labels = percent, name = "累积占比 (%)")
  ) +
  theme_minimal()

关键调整点

  • 直方图:将y=..density..替换为y=..sum..,结合weight=tonne.km,直接输出区间内tonne.km的总和,而非归一化的密度值。
  • 累积曲线:
    • 必须添加weight=tonne.km,确保累积计算基于tonne.km的权重,而非样本数量。
    • 用cumsum(..sum..) / sum(..sum..)将累积总和转换为占比,匹配右侧次轴的百分比格式。
    • 添加group=1,避免ggplot因分组逻辑中断线条绘制。

预处理数据实现(更透明)

如果需要更直观地控制数据分组和计算逻辑,可以提前预处理数据,再绘制图表:

# 计算总tonne.km,用于后续占比转换
total_tk <- sum(dist.tk.test$tonne.km)

# 分组计算每个distance区间的tonne.km总和与累积占比
dist_binned <- dist.tk.test %>%
  mutate(distance_bin = cut(distance, breaks = 50)) %>%
  group_by(distance_bin) %>%
  summarise(tk_sum = sum(tonne.km)) %>%
  mutate(
    # 取区间中点作为x轴绘制位置
    distance_mid = map_dbl(distance_bin, ~mean(as.numeric(.)[1:2])),
    # 计算累积占比
    cumulative_pct = cumsum(tk_sum) / total_tk
  )

# 绘图
ggplot(dist_binned) +
  geom_col(aes(x = distance_mid, y = tk_sum), fill = "lightblue", alpha = 0.7) +
  # 将累积占比转换为主轴同单位,再通过次轴转换回百分比
  geom_line(aes(x = distance_mid, y = cumulative_pct * total_tk), color = "red", size = 1) +
  scale_x_continuous(label = comma, breaks = extended_breaks(10)) +
  scale_y_continuous(
    name = "Tonne.km 总和",
    labels = comma,
    sec.axis = sec_axis(~ . / total_tk, labels = percent, name = "累积占比 (%)")
  ) +
  theme_minimal()

预处理优势

可以直接查看每个区间的具体数值,方便后续分析;同时灵活控制bin的划分规则(比如自定义断点)。


内容的提问来源于stack exchange,提问作者David Færgeman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:24:21