如何为geom_curve设置Y轴范围,使绘图区域适配最高拱高度?
解决geom_curve绘图区域适配最高拱的问题
问题描述
尝试设置geom_curve绘图的高度,让绘图区域刚好截止在“最高拱”的上方,使用ylim()未达到预期效果,寻求可行方法。
原代码
df <- data.frame(x1 = c(9,10,11,12,13), x2 = c(25,24,23,22,210), y1 = c(0,0,0,0,0), y2 = c(0,0,0,0,0), fill = c(rep('black',5))) ggplot(df) + geom_curve(aes(x=x1, xend=x2, y=y1, yend=y2), curvature=1, linewidth=0.5, ncp=1000, colour='black') + expand_limits(y=1) + scale_y_reverse() + theme(axis.text.x = element_text(size=9, angle=0, vjust=0.5), axis.text.y = element_text(size=9), legend.position = 'none', axis.title.x = element_blank(), axis.title.y = element_blank(), plot.margin = margin(10,0,0,0))
示例图

解决方案
核心思路是先提取geom_curve生成的曲线实际坐标数据,找到曲线的最高点,再根据这个高度精准设置y轴范围:
- 先绘制基础图形并保存为对象;
- 提取曲线的坐标数据,计算出曲线的最大y值(因使用
scale_y_reverse(),原坐标系的最大y值对应绘图区域的顶部); - 基于最大y值设置
ylim(),可额外添加少量边距避免曲线紧贴绘图区域顶部。
修改后完整代码
df <- data.frame(x1 = c(9,10,11,12,13), x2 = c(25,24,23,22,210), y1 = c(0,0,0,0,0), y2 = c(0,0,0,0,0), fill = c(rep('black',5))) # 绘制基础图形并保存 p <- ggplot(df) + geom_curve(aes(x=x1, xend=x2, y=y1, yend=y2), curvature=1, linewidth=0.5, ncp=1000, colour='black') + scale_y_reverse() + theme(axis.text.x = element_text(size=9, angle=0, vjust=0.5), axis.text.y = element_text(size=9), legend.position = 'none', axis.title.x = element_blank(), axis.title.y = element_blank(), plot.margin = margin(10,0,0,0)) # 提取曲线坐标数据,计算最高点y值 curve_data <- ggplot_build(p)$data[[1]] max_y <- max(curve_data$y) # 设置y轴范围,添加5%边距避免紧贴顶部 p + ylim(max_y * 1.05, 0)
说明
- 之前
ylim()无效是因为未基于曲线实际高度设置范围,expand_limits(y=1)只是强制扩展到y=1,但无法匹配真实曲线高度; - 通过
ggplot_build(p)$data[[1]]可提取图层的原始坐标数据,确保获取的最高点是曲线的真实顶点; - 乘以1.05是为了给顶部留少量空白,若不需要可直接用
max_y作为y轴上限。
内容的提问来源于stack exchange,提问作者steven_opp
相关产品推荐
相关产品推荐

