我尝试使用
这是一个最小化的工作示例:
library(scales)
和scale_color_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))
)
}
情节:
1. 使用简单刻度的图表 - 异常值会导致刻度拉伸。
ggplot(data1, aes(x = x, y = y, color = v1))+
geom_point()+
col2
2. 使用调整后的比例尺绘图 - 正确的颜色比例尺。
ggplot(data1, aes(x = x, y = y, color = v1))+
geom_point()+
coln
3. v1
的刻度不适用于v2
,因为数据不同。
ggplot(data1, aes(x = x, y = y, color = v2))+
geom_point()+
coln
#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
}
}
4. 第一个图的刻度有误。
plots[[1]]
5. 第二张图的比例尺正确。
plots[[2]]
所以我猜这可能与在绘图时调用scale_color_gradientn()
函数有关,而不是在循环内部调用。
如果有人能帮助解决这个问题,将不胜感激。在基础R中,我会对连续数据进行分组,并将十六进制颜色分配到用于填充颜色的向量中,但我不确定如何在ggplot中应用它。
colm
中的一个函数?),该函数访问了来自该环境中aa
、bb
、cc
和dd
的最后一个值。这里我的理解正确吗?我想我不太明白为什么i
成功传递到ggplot()
函数,而计算出的aa
等值没有传递。这是否与ggplot()
返回类型与scale_color_gradientn()
返回类型有关? - Duncan Murrayggplot() + ...
结构的不同部分在不同的时间被评估(初始构建与绘图时)。在您编写的代码中,当您调用plot [[1]]
时,scale_color_gradientn()
的参数仅在该时间被评估,并且此时aa
、bb
等的内容对应于最后一个图。在 R 中,您永远无法确定函数将在何时在哪个环境中进行评估。这就是为什么闭包是这些编码场景的通用方法的原因。 - Claus Wilke