R语言双Y轴散点图坐标轴设置问题及ggplot实现方法
双Y轴散点图实现方案
原代码出现标签重叠、刻度异常的核心原因有两个:一是第二个图层X轴错用anneemut变量,和主图层X轴valeurfonc不匹配导致坐标体系错位;二是未手动指定坐标轴参数,默认生成的刻度、标签不符合需求。以下分别给出base R修复版本和ggplot2实现版本。
1. Base R 修复版代码
修复逻辑对应问题点逐一调整:
- 绘图初始关闭科学计数法,避免X轴出现科学计数格式
- 第一个主图层直接定义好X、Y轴标签,第二个叠加图层强制清空轴标签,从根源避免标签重叠
- 手动指定第一Y轴(年份)的刻度值为数据集中所有出现的年份,保证刻度完整
- 修正第二个图层的X轴映射变量,和主图层保持一致,统一坐标体系
# 全局关闭科学计数法 options(scipen = 999) # 调整画布边距,为第二Y轴预留展示空间 par(mar = c(5, 4, 4, 4) + 0.3) # 绘制第一个散点图层:X轴映射交易价格,左Y轴映射交易年份 plot( x = px$valeurfonc, y = px$anneemut, pch = 16, col = 2, xlab = "交易价格(valeurfonc)", ylab = "交易年份(anneemut)", yaxt = "n" # 关闭默认Y轴,后续手动添加完整年份刻度 ) # 手动添加左Y轴刻度,展示数据集中所有出现的年份 axis(side = 2, at = sort(unique(px$anneemut))) # 叠加第二个散点图层 par(new = TRUE) plot( x = px$valeurfonc, # 修正原代码的X变量映射错误,和主图层X轴保持一致 y = px$sbati, pch = 17, col = 3, axes = FALSE, # 关闭默认坐标轴,避免覆盖主图层 xlab = "", # 清空轴标签,避免和主图层标签重叠 ylab = "" ) # 添加右Y轴刻度与标签 axis(side = 4, at = pretty(range(px$sbati, na.rm = TRUE))) mtext("房屋面积(sbati)", side = 4, line = 3) # 添加图例区分两组散点 legend( "topright", legend = c("交易年份", "房屋面积"), pch = c(16,17), col = c(2,3) )
2. ggplot2 实现版本
ggplot2从2.2.0版本开始支持sec_axis()函数实现双Y轴,由于两个Y轴量纲差异较大(年份为2014以上的四位整数,面积为几十到几百的数值),需要先计算缩放系数将次轴数据缩放到主轴数值范围,再在次轴定义时反向还原为真实刻度值:
library(ggplot2) # 全局关闭科学计数法 options(scipen = 999) # 计算双Y轴缩放系数:将面积值映射到年份的数值区间 y_range_year <- range(px$anneemut, na.rm = TRUE) y_range_sbati <- range(px$sbati, na.rm = TRUE) scale_factor <- diff(y_range_year) / diff(y_range_sbati) ggplot(px, aes(x = valeurfonc)) + # 左Y轴散点:映射交易年份 geom_point(aes(y = anneemut, color = "交易年份", shape = "交易年份"), size = 2) + # 右Y轴散点:映射房屋面积,先按系数做缩放适配主轴范围 geom_point(aes(y = (sbati - y_range_sbati[1])*scale_factor + y_range_year[1], color = "房屋面积", shape = "房屋面积"), size = 2) + # 配置X轴:使用逗号格式标注数值,禁用科学计数法 scale_x_continuous(name = "交易价格(valeurfonc)", labels = scales::comma) + # 配置双Y轴 scale_y_continuous( name = "交易年份(anneemut)", breaks = sort(unique(px$anneemut)), # 左Y轴显示所有年份刻度 # 配置右Y轴,反向缩放还原为真实面积刻度 sec.axis = sec_axis( trans = ~(. - y_range_year[1])/scale_factor + y_range_sbati[1], name = "房屋面积(sbati)" ) ) + # 自定义散点的颜色和形状 scale_color_manual(values = c("交易年份" = 2, "房屋面积" = 3)) + scale_shape_manual(values = c("交易年份" = 16, "房屋面积" = 17)) + theme_bw() + theme( axis.title.y.right = element_text(color = 3), axis.text.y.right = element_text(color = 3), axis.title.y.left = element_text(color = 2), axis.text.y.left = element_text(color = 2), legend.position = "top", legend.title = element_blank() )
注意:双Y轴图表容易因刻度缩放比例问题造成视觉误导,正式分析场景建议优先使用分面图替代双Y轴做多变量展示。
内容的提问来源于stack exchange,提问作者mmcr_economics
相关产品推荐
相关产品推荐

