如何用R语言ggplot2绘制平行线?循环绘图仅显示一条线求助
问题排查与解决
问题原因
- 循环变量
x和之前定义的序列变量x重名,覆盖了原始数据的x向量,导致后续计算逻辑混乱。 - ggplot2的
aes()采用延迟求值机制,循环中添加的geom_line不会立即计算y的值,循环结束后所有图层的y表达式都会使用循环最后一次的x值(即6),因此最终仅显示一条线。
解决方案
方案1:修正循环变量名并强制即时求值
将循环变量名改为i避免覆盖原始序列,同时用!!强制表达式即时求值:
library(ggplot2) plot_constraints <- function() { x <- seq(-5, 25, by = 0.1) f1 <- (141000 - 4000*x) / 5000 f2 <- 17 f3 <- 19 obj.func <- (-3*x/5) df <- data.frame(x, f1) p <- ggplot(df, aes(x = x)) dice <- c(1, 2, 3, 4, 5, 6) for (i in dice) { p <- p + geom_line(aes(y = obj.func + !!i), color = "grey", lwd=0.5) } p <- p + geom_line(aes(y = f1), color = "red", lwd=1.4) + geom_vline(xintercept = f3, color = "green", lwd=1.4) + geom_hline(yintercept = f2, color = "blue", lwd=1.4) + geom_vline(xintercept = 0, color = "black", lwd=1.4) + geom_hline(yintercept = 0, color = "black", lwd=1.4) + coord_cartesian(xlim = c(0, 20), ylim = c(0, 20)) + labs(x = "Three-tonne trucks", y = "Five-tonne trucks") + theme_classic() p } plot_constraints()
方案2:数据驱动绘制(推荐,更贴合ggplot2风格)
无需循环,直接构造包含所有偏移值的长数据框,一次性绘制所有平行线:
library(ggplot2) library(dplyr) library(tidyr) plot_constraints <- function() { x <- seq(-5, 25, by = 0.1) f1 <- (141000 - 4000*x) / 5000 f2 <- 17 f3 <- 19 obj.func <- (-3*x/5) # 构造包含所有偏移值的长数据 df_obj <- data.frame(x) %>% mutate( base = obj.func, offset1 = base + 1, offset2 = base + 2, offset3 = base + 3, offset4 = base + 4, offset5 = base + 5, offset6 = base + 6 ) %>% pivot_longer(cols = starts_with("offset"), names_to = "offset", values_to = "y") df_f1 <- data.frame(x, f1) ggplot() + geom_line(data = df_obj, aes(x = x, y = y), color = "grey", lwd=0.5) + geom_line(data = df_f1, aes(x = x, y = f1), color = "red", lwd=1.4) + geom_vline(xintercept = f3, color = "green", lwd=1.4) + geom_hline(yintercept = f2, color = "blue", lwd=1.4) + geom_vline(xintercept = 0, color = "black", lwd=1.4) + geom_hline(yintercept = 0, color = "black", lwd=1.4) + coord_cartesian(xlim = c(0, 20), ylim = c(0, 20)) + labs(x = "Three-tonne trucks", y = "Five-tonne trucks") + theme_classic() } plot_constraints()
说明
方案2是ggplot2的推荐实践,通过整理数据结构实现多图层绘制,既避免了循环带来的求值问题,代码也更易维护和扩展。
内容的提问来源于stack exchange,提问作者Beef Fat
相关产品推荐
相关产品推荐

