for 循环中 ggplots geom_point 的奇怪行为
Strange behavior with ggplots geom_point in for loop
我正在使用 ggplot
和 gridExtra
用不同的数据并排绘制两个图,并且在使用矢量而不是数据框来绘制图时我观察到了意外行为。
这是我遇到的问题的 MWE:
library(ggplot2)
library(dplyr)
library(gridExtra)
cases <- c(1, 2)
df <- data.frame(
case=cases,
y1=c(1, 2),
y2=c(2, 4),
y3=c(3, 8),
y4=c(4, 16),
y5=c(5, 32)
)
x <- c(1, 2, 3, 4, 5)
plot_list <- list()
for(caso in cases){
data <- df %>% filter(case == caso)
y <- data %>% dplyr::select(starts_with('y')) %>% unlist(use.name=FALSE)
dd <- data.frame(xdf=x, ydf=y)
graph <- (
ggplot()
+ geom_line(data=dd, aes(x=xdf, y=ydf))
## + geom_point(data=dd, aes(x=xdf, y=ydf)) # this line works
+ geom_point(aes(x=x, y=y)) # this line doesn't
)
plot_list[[length(plot_list)+1]] <- graph
}
grid.arrange(grobs=plot_list, ncol=2)
这段代码制作了一个图,左边是直线,右边是抛物线。我标记了调用 geom_point
的两行。如果我将行与数据框一起使用,一切都会按预期进行。但是,如果我使用带向量的线(实际上用于创建数据框),那么抛物线的点将绘制在所有图形中。
这是结果图:
显然,问题是通过使用数据帧而不是向量来解决的,但我首先想了解为什么会发生这种行为。因此,对于为什么 R 以这种看似违反直觉(至少对我而言)的方式行事的任何见解,我将不胜感激。
有趣的发现。这是因为您使用的是 for 循环,而且它们对我来说也经常难以理解有关对象创建和评估的行为。在您的情况下,ggplot 直到最后一端才绘制绘图,然后最后一个向量 'y' 用于绘图。我发现避免此问题的最简单方法是使用另一种循环方式。我更喜欢申请家庭。
也就是说 - 我的建议是避免在 aes()
中使用向量 - 这只会引起头痛。
我刚刚发现这个线程可以更好地解释问题。建议将此问题作为重复问题关闭。 "for" loop only adds the final ggplot layer
library(ggplot2)
library(dplyr)
df <- data.frame( case=1:2, y1=c(1, 2), y2=c(2, 4), y3=c(3, 8), y4=c(4, 16), y5=c(5, 32))
x <- 1:5
plot_list <- lapply(1:2, function(i){
data <- df %>% dplyr::filter(case == i)
y <- data %>% dplyr::select(starts_with('y')) %>% unlist(use.name=FALSE)
graph <- ggplot() +
geom_point(aes(x=x, y=y))
graph
})
gridExtra::grid.arrange(grobs=plot_list, ncol=2)
由 reprex package (v2.0.1)
于 2022-02-08 创建
我正在使用 ggplot
和 gridExtra
用不同的数据并排绘制两个图,并且在使用矢量而不是数据框来绘制图时我观察到了意外行为。
这是我遇到的问题的 MWE:
library(ggplot2)
library(dplyr)
library(gridExtra)
cases <- c(1, 2)
df <- data.frame(
case=cases,
y1=c(1, 2),
y2=c(2, 4),
y3=c(3, 8),
y4=c(4, 16),
y5=c(5, 32)
)
x <- c(1, 2, 3, 4, 5)
plot_list <- list()
for(caso in cases){
data <- df %>% filter(case == caso)
y <- data %>% dplyr::select(starts_with('y')) %>% unlist(use.name=FALSE)
dd <- data.frame(xdf=x, ydf=y)
graph <- (
ggplot()
+ geom_line(data=dd, aes(x=xdf, y=ydf))
## + geom_point(data=dd, aes(x=xdf, y=ydf)) # this line works
+ geom_point(aes(x=x, y=y)) # this line doesn't
)
plot_list[[length(plot_list)+1]] <- graph
}
grid.arrange(grobs=plot_list, ncol=2)
这段代码制作了一个图,左边是直线,右边是抛物线。我标记了调用 geom_point
的两行。如果我将行与数据框一起使用,一切都会按预期进行。但是,如果我使用带向量的线(实际上用于创建数据框),那么抛物线的点将绘制在所有图形中。
这是结果图:
显然,问题是通过使用数据帧而不是向量来解决的,但我首先想了解为什么会发生这种行为。因此,对于为什么 R 以这种看似违反直觉(至少对我而言)的方式行事的任何见解,我将不胜感激。
有趣的发现。这是因为您使用的是 for 循环,而且它们对我来说也经常难以理解有关对象创建和评估的行为。在您的情况下,ggplot 直到最后一端才绘制绘图,然后最后一个向量 'y' 用于绘图。我发现避免此问题的最简单方法是使用另一种循环方式。我更喜欢申请家庭。
也就是说 - 我的建议是避免在 aes()
中使用向量 - 这只会引起头痛。
我刚刚发现这个线程可以更好地解释问题。建议将此问题作为重复问题关闭。 "for" loop only adds the final ggplot layer
library(ggplot2)
library(dplyr)
df <- data.frame( case=1:2, y1=c(1, 2), y2=c(2, 4), y3=c(3, 8), y4=c(4, 16), y5=c(5, 32))
x <- 1:5
plot_list <- lapply(1:2, function(i){
data <- df %>% dplyr::filter(case == i)
y <- data %>% dplyr::select(starts_with('y')) %>% unlist(use.name=FALSE)
graph <- ggplot() +
geom_point(aes(x=x, y=y))
graph
})
gridExtra::grid.arrange(grobs=plot_list, ncol=2)
由 reprex package (v2.0.1)
于 2022-02-08 创建