在ggplot2中使用scale\U color\U GRADIENT生成的绘图列表颜色错误

在ggplot2中使用scale\U color\U GRADIENT生成的绘图列表颜色错误,r,ggplot2,R,Ggplot2,我试图使用库(scales)和scale\u color\u gradientn()创建颜色到连续变量的自定义映射,以限制异常值对绘图颜色的影响。这适用于单个绘图,但在使用循环生成多个绘图并将其存储在列表中时不起作用 下面是一个简单的工作示例: library(ggplot2) library(scales) data1 <- as.data.frame(cbind(x = rnorm(100), y = rnorm(100),

我试图使用
库(scales)
scale\u color\u gradientn()
创建颜色到连续变量的自定义映射,以限制异常值对绘图颜色的影响。这适用于单个绘图,但在使用循环生成多个绘图并将其存储在列表中时不起作用

下面是一个简单的工作示例:

library(ggplot2)
library(scales)

data1 <- as.data.frame(cbind(x = rnorm(100),
                             y = rnorm(100),
                             v1 = rnorm(100, mean = 2, sd = 1),
                             v2 = rnorm(100, mean = -2, sd = 1)))

#add outliers
data1[1,"v1"] <- 200
data1[2,"v1"] <- -200
data1[1,"v2"] <- 50
data1[2,"v2"] <- -50

#define color palette
cols <- colorRampPalette(c("#3540FF","black","#FF3535"))(n = 100)

#simple color scale
col2 <- scale_color_gradient2(low = "#3540FF",
                              mid = "black",
                              high = "#FF3535"
                              )

#outlier-adjusted color scale
{
    aa <- min(data1$v1)
    bb <- quantile(data1$v1, 0.05)
    cc <- quantile(data1$v1, 0.95)
    dd <- max(data1$v1)

    coln <- scale_color_gradientn(colors = cols[c(1,5,95,100)],
               values = rescale(c(aa,bb,cc,dd),
                    limits = c(aa,dd))
                                                                 )
}

二,。使用异常值调整比例打印-正确的颜色比例

ggplot(data1, aes(x = x, y = y, color = v1))+
    geom_point()+
    coln

三,。由于数据不同,
v1
的刻度不适用于
v2

ggplot(data1, aes(x = x, y = y, color = v2))+
    geom_point()+
    coln

五,。第二个图的比例正确

plots[[2]]

所以我猜这与绘图时调用的
scale\u color\u gradientn()
函数有关,而不是在循环中

如果有人能帮上忙,我将不胜感激。在base R中,我将存储连续数据,并将十六进制颜色分配到用于填充颜色的向量中,但我不确定如何在ggplot中应用这一点。

您需要使用闭包(具有相关环境的函数):


谢谢您的回答。据我所知,我的示例不起作用的原因是因为在绘图时调用了一个函数(我认为它是对象
colm
?)中的一个函数,该函数从该环境访问
aa
bb
cc
dd
的最后值。我的理解正确吗?我想我不太明白为什么
I
被成功地传递到
ggplot()
函数,而
aa
等的计算值却没有。这与
ggplot()
返回的类型与
scale\u color\u gradientn()
返回的类型有关吗?
ggplot()+…
构造的不同部分在不同的时间进行评估(初始构造与打印绘图时)。在您编写的代码中,
scale\u color\u gradientn()
的参数仅在调用
plot[[1]]
时才进行计算,此时
aa
bb
等的内容对应于最后一个绘图。在R中,您永远无法确定函数将在何时以及在哪个环境中进行求值。这就是为什么闭包是处理这类编码场景的通用方法。太棒了,这很有意义。再次感谢。
#loop to produce list of plots each with own scale
{
    plots <- list()
    k <- 1
    for (i in c("v1","v2")){
        aa <- min(data1[,i])
        bb <- quantile(data1[,i],0.05)
        cc <- quantile(data1[,i], 0.95)
        dd <- max(data1[,i])

        colm <- scale_color_gradientn(colors = cols[c(1,5,95,100)],
                     values = rescale(c(aa,bb,cc,dd),
                         limits = c(aa,dd)))

        plots[[k]] <- ggplot(data1, aes_string(x = "x",
                                               y = "y",
                                                   color = i
                                                   ))+
                     geom_point()+
                     colm

        k <- k + 1
    }
}
plots[[1]]
plots[[2]]
{
  plots <- list()
  k <- 1
  for (i in c("v1", "v2")){
    colm <- function() {
      aa <- min(data1[, i])
      bb <- quantile(data1[, i], 0.05)
      cc <- quantile(data1[, i], 0.95)
      dd <- max(data1[, i])

      scale_color_gradientn(colors = cols[c(1, 5, 95, 100)],
                            values = rescale(c(aa, bb, cc, dd),
                            limits = c(aa, dd)))
    }

    plots[[k]] <- ggplot(data1, aes_string(x = "x",
                                           y = "y",
                                           color = i)) +
                    geom_point() +
                    colm()
    k <- k + 1
  }
}

plots[[1]]
plots[[2]]