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
相关产品推荐
相关产品推荐

