R语言ggplot中如何编程生成geom_segment避免重复代码调用
解决方案
你要实现的效果本质是为每个频率值绘制一段从当前时间点到下一个时间点的水平线,不需要重复写geom_segment代码,以下是两种适配任意行数数据框的实现方案:
方案1(更推荐,符合ggplot2语法逻辑)
提前构造带线段终点坐标的数据集,仅用一行geom_segment即可完成绘制,运行效率更高、代码更简洁:
library(ggplot2) library(tibble) library(dplyr) df <- tibble(freqs = c(261.6256, 293.6648, 329.6276, 293.6648, 329.6276, 349.2282, 391.9954, 349.2282, 329.6276, 293.6648, 329.6276, 293.6648, 329.6276, 349.2282, 391.9954), durs = c(0.96, 1.92, 3.84, 4.80, 5.76, 7.68, 8.64, 9.60, 10.56, 11.52, 12.00, 12.48, 12.96, 13.44, 15.36)) # 自动计算每段线段的x轴终点,default参数对应最后一段的终点值,可按需调整 df_plot <- df %>% mutate(xend = lead(durs, default = 16)) # 绘图仅需一行geom_segment,自动适配任意行数的输入数据 ggplot(df_plot, aes(x = durs, y = freqs)) + geom_segment(aes(xend = xend, yend = freqs))
方案2(批量生成geom_segment调用)
完全匹配你要求的「编程批量生成多个geom_segment调用」的需求,通过循环生成图层列表后直接添加到ggplot对象即可:
library(ggplot2) library(tibble) df <- tibble(freqs = c(261.6256, 293.6648, 329.6276, 293.6648, 329.6276, 349.2282, 391.9954, 349.2282, 329.6276, 293.6648, 329.6276, 293.6648, 329.6276, 349.2282, 391.9954), durs = c(0.96, 1.92, 3.84, 4.80, 5.76, 7.68, 8.64, 9.60, 10.56, 11.52, 12.00, 12.48, 12.96, 13.44, 15.36)) n <- nrow(df) # 批量生成geom_segment图层列表 seg_list <- lapply(1:n, function(i){ x_end <- ifelse(i < n, df$durs[i+1], 16) # 最后一段的终点值可按需调整 geom_segment(aes(x = df$durs[i], xend = x_end, y = df$freqs[i], yend = df$freqs[i])) }) # 直接添加图层列表即可完成绘图 ggplot(df, aes(x = durs, y = freqs)) + seg_list
两种方案输出的可视化效果和你原代码手动写15行geom_segment的效果完全一致。
内容的提问来源于stack exchange,提问作者eartoolbox
相关产品推荐
相关产品推荐

