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

R语言ggplot双Y轴柱状图与折线图组合绘制问题求助

问题原因及解决方法

1. 折线图与次Y轴不显示的问题

原因有两个:

  • geom_line()代码行末尾缺失+号,导致后续的scale_y_continuous()语句没有被加入ggplot绘图对象,次Y轴不会被渲染。
  • 你直接使用的rate、lowerrate、upperrate属于率值,数值范围远小于主Y轴的发病例数num,直接绘制的话折线和置信带会贴在X轴底部,视觉上看不到。

解决方法:
先手动计算缩放系数,将率值的数值范围映射到和主Y轴发病例数相近的范围,再进行绘图。

2. sec_axis()调用atrisk报错的问题

sec_axis()的变换规则仅支持对主Y轴的输入数值做运算,无法直接调用数据集内的atrisk变量,因此会触发非单调变换的报错。次Y轴本质只是标签映射,不需要在变换中调用数据集变量,只需通过缩放系数做反向转换即可得到真实的率值。


修正后的完整代码示例

# 先计算缩放系数,可根据实际数据分布调整比例
coef <- max(inc$num, na.rm = TRUE) / max(c(inc$rate, inc$upperrate), na.rm = TRUE)

ggplot(inc, aes(x = age, fill = sex)) +
  geom_bar(aes(y = num), stat = "identity", position = "dodge", color = "black", width = 0.6) +
  geom_errorbar(aes(ymin = num - se, ymax = num + se), width = 0.3, position = position_dodge(0.6)) +
  # 率相关图层乘缩放系数,匹配主Y轴范围
  geom_ribbon(aes(ymin = lowerrate * coef, ymax = upperrate * coef, group = sex), alpha = 0.3) +
  geom_line(aes(y = rate * coef, group = sex, color = sex)) +
  # 次Y轴做反向变换得到真实率值,转为10万人发病率
  scale_y_continuous(sec.axis = sec_axis(~ . / coef * 100000, name = "每10万人发病率")) +
  scale_fill_brewer(palette = "Pastel1", limits = c("Female", "Male")) +
  # 匹配折线颜色和柱形填充色
  scale_color_brewer(palette = "Pastel1", limits = c("Female", "Male")) +
  labs(x = "年龄(岁)", y = "发病例数") +
  theme_classic() +
  theme(
    legend.position = "top",
    legend.justification = "left"
  )

如果需要按性别区分折线和置信带,可直接去掉group = sex,改为将color = sex放入全局aes中即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:54:05