当绘图保存在列表中时,变量 geom_text 被覆盖

Variable geom_text is overwritten when plots saved in list

我正在尝试使用 ggarrange 组织几十个地块,所以我设置了一个循环,将每个地块保存在一个列表中。每个图都因数据、标题等不同而各不相同。在我尝试使用 geom_text 在图中放置一些文本之前,一切都完美无缺。当绘图保存在列表中时,每个绘图都继承列表中最后一个绘图的 geom_text。我不知道如何避免这种情况。

my.list=vector("list", length = 2);
dt=data.table(x=c(1,100,100000),y=c(1,100,100000))
plotname=c('first','second')

for (i in 1:length(my.list)) {
 my.list[[i]]=ggplot(data = dt, aes(x = x, y = y ))  + geom_point(size=1.5,aes(color=c('red'))) + labs(x=NULL, y=NULL) 
+ scale_color_manual(values='red') 
+ theme_bw() + theme(panel.background = element_rect(fill='light grey', colour='black'),legend.position = "none") 
+ geom_text(inherit.aes=FALSE,aes(x=500, y=100000, label=paste0('NRMSE:',i))) + ggtitle(paste0(plotname[i])) + coord_equal() 
+ geom_abline(slope=1) 
+ scale_y_log10(breaks = c(1,10,100,1000,10000,100000),limits=c(1,100000)) 
+ scale_x_log10(breaks = c(1,10,100,1000,10000,1000000),limits=c(1,100000)) 
+ labs(x=NULL, y=NULL) 
+ theme_bw() + theme(panel.background = element_rect(fill='light grey', colour='black'),legend.position = "none")
}

之后我做

plotosave=ggarrange(plotlist=my.list)

我不完全知道为什么会发生这种情况,但是如果您从 geom_text 中删除 aes 它会起作用。

library(ggplot2)

my.list = vector("list", length = 2)
dt = data.table::data.table(x=c(1,100,100000),y=c(1,100,100000))
plotname = c('first','second')

for (i in 1:length(my.list)) {

  my.list[[i]]= ggplot(data = dt, aes(x = x, y = y ))  + 
                 geom_point(size=1.5) + 
                 labs(x=NULL, y=NULL) + 
                 theme_bw() + 
                 theme(panel.background = element_rect(fill='light grey', colour='black'),
                       legend.position = "none") + 
                 geom_text(x=50000, y=100000, label=paste0('NRMSE:',i)) + 
                 ggtitle(paste0(plotname[i]))
}
plotosave = ggpubr::ggarrange(plotlist=my.list)

使用 lapply 代替 forloop 效果很好:

my.list <- lapply(1:2, function(i) {
  ggplot(data = dt, aes(x = x, y = y ))  + 
    geom_point(size=1.5) + 
    labs(x=NULL, y=NULL) + 
    theme_bw() + 
    theme(panel.background = element_rect(fill='light grey', colour='black'),
          legend.position = "none") + 
    geom_text(inherit.aes=FALSE,aes(x=50000, y=100000, 
                                    label=paste0('NRMSE:',i))) + 
    ggtitle(paste0(plotname[i]))
  })

ggarrange(plotlist = my.list)

注意:问题不在于 ggarrange


Roland:

The plot is build when you print the ggplot object. Anything that is not part of the data passed will be taken from the enclosing environment at exactly that time point. If you use the iterator of a for loop in the plot, it has its last value then (or any value you change it to later on). lapply avoids the issue because of the stuff explained in the Note in its documentation.


Related post:

the problem is that ggplot() waits until you print the plot to resolve the variables in the aes() command.