ggplot2配置双数据集双Y轴时两数据仍共用主轴问题解决
问题根源
ggplot2的次坐标轴不具备自动映射数据的能力,它本质是在主坐标轴旁新增一套经过固定公式转换的刻度标签,所有geom_*对象默认都在主Y轴的坐标空间渲染。你没有对incr_eur做对应比例的缩放就直接传入绘图,自然两条线都会按主Y轴刻度定位。
另外你的代码还有一个低级错误:函数最后返回的是数据表avg_section,不是绘图对象avg_dual_plots,就算绘图逻辑写对也拿不到正确的图。
修正方案
你需要做两步匹配:
- 先计算两个Y轴的数值缩放比例,把次轴对应的
incr_eur值按比例缩放到主Y轴的数值范围内,再传给geom_line绘图 - 次轴的转换公式必须和你缩放数据的公式完全反向,保证次轴刻度和
incr_eur的真实值对应
修正后可运行代码
# 用到rescale函数需先加载scales包,若未安装可先执行install.packages("scales") library(scales) avg_dual_plot <- function(reservoir_model, simulation_case, optimal_spacing, Wells_per_section, well_eur, tolerance){ avg_section <- qualified_eur %>% dplyr::group_by(Wells_per_section) %>% dplyr::summarise(mean_section_eur = mean(section_eur)) %>% dplyr::mutate(incr_eur = incrementalEUR(mean_section_eur)) # 计算双轴缩放比例,让两个指标的线都能在绘图区域完整展示 main_axis_upper <- max(avg_section$mean_section_eur) * 1.05 # 留5%的边距 sec_axis_upper <- max(avg_section$incr_eur) * 1.05 scale_ratio <- main_axis_upper / sec_axis_upper avg_dual_plots <- avg_section %>% # 原代码这里重复传入了avg_section参数,管道操作后不需要再写一次 ggplot2::ggplot(mapping = aes(x = Wells_per_section)) + geom_line(aes(y = mean_section_eur, color = "平均段EUR"), linewidth = 1) + # 次轴数据必须先按比例缩放到主轴坐标空间 geom_line(aes(y = incr_eur * scale_ratio, color = "增量EUR"), linewidth = 1) + scale_y_continuous( name = "段平均EUR", # 次轴转换反向缩放,还原为增量EUR的真实刻度 sec.axis = sec_axis(trans = ~ . / scale_ratio, name = "增量EUR") ) + # 新增颜色图例区分两条折线 scale_color_manual( values = c("平均段EUR" = "#2c3e50", "增量EUR" = "#e74c3c"), name = "指标类型" ) # 修正返回值,返回绘图对象而非数据表 return(avg_dual_plots) }
补充说明
如果你想固定次轴范围为0~500000,只需要把上面代码里的sec_axis_upper改成500000即可,缩放逻辑不需要改动。
内容的提问来源于stack exchange,提问作者Solicia
相关产品推荐
相关产品推荐

