使用ggplot2在同一绘图中添加双柱状图(不同刻度)的技术问询
解决方案
一、双刻度并列柱状图(修复次坐标轴不显示问题)
ggplot的sec.axis本质是对主坐标轴的数值做变换,不能直接绑定两组独立数据,这是你之前次轴没显示的核心原因。要实现双刻度并列柱状图,需要先对其中一类数据(比如洪涝相关的discharge/gauges)做缩放,映射到主轴范围后,再通过次轴还原真实刻度。
步骤1:整理数据为长格式
先把宽格式数据转成tidy格式,新增Category列标记变量属于气候(Climate)还是洪涝(Floods),示例结构如下:
| Year | Variable | Value | Category |
|---|---|---|---|
| 2016 | maxtemp | 28.5 | Climate |
| 2016 | discharge_site1 | 1200 | Floods |
步骤2:绘图代码示例
library(ggplot2) library(dplyr) # 计算洪涝数据的缩放比例(匹配气候数据的数值范围) flood_scale <- max(df$Value[df$Category == "Climate"]) / max(df$Value[df$Category == "Floods"]) ggplot(df, aes(x = interaction(Year, Variable), y = ifelse(Category == "Floods", Value * flood_scale, Value), fill = Category)) + geom_col(position = "dodge", width = 0.7) + # 主坐标轴(气候变量) scale_y_continuous( name = "气候变量(年平均值)", # 次坐标轴(洪涝变量,还原缩放比例) sec.axis = sec_axis(~ . / flood_scale, name = "洪涝变量(年平均值)") ) + # 简化x轴标签,只显示年份 scale_x_discrete(labels = function(x) gsub("\\..*", "", x)) + labs(x = "年份", fill = "变量类别") + theme(axis.text.x = element_text(angle = 45, hjust = 1))
这样就能实现同一年份下,气候与洪涝变量的柱子并列,同时显示双刻度坐标轴。
二、风向变量的处理建议
风向是角度/分类数据,年平均值完全没有实际意义(比如全年一半吹东北风、一半吹西南风,平均值会指向西北风,但这并不是真实的主导风向)。针对你的场景:
- 如果风向是分析重点:用年众数(统计全年出现频率最高的风向)作为该年的代表值,能真实反映年度主导风向。预处理代码示例:
不过风向是分类数据,和其他连续型气候变量放在同一柱状图会不协调,建议单独做小图展示(比如年度主导风向条形图)。# 假设原始数据包含Year和windirection列(角度或分类值) df_wind <- df %>% filter(Variable == "windirection") %>% group_by(Year) %>% mutate(yearly_dominant_wind = names(which.max(table(windirection)))) %>% ungroup() - 如果风向不是核心分析变量:直接移除,避免干扰图表的可读性和简洁性。
三、额外优化建议
- 若变量过多(6个气候+2个洪涝),同一年份并列8个柱子会过于拥挤,建议:
- 只保留核心变量(比如气候选降雨量、最高温,洪涝选站点流量);
- 按变量类别分面展示(用
facet_wrap(~ Category))。
- 使用次坐标轴时,建议在图表注释中标注缩放关系,避免误导读者。
内容的提问来源于stack exchange,提问作者Teema
相关产品推荐
相关产品推荐

