据我所知,没有一种简单的方法,但您可以完全控制使用scale_fill_gradientn. 关键是将颜色映射到 0-1 范围内的值,其中 0 是最小值,1 是最大值。这是一个选项:
library(ggplot2)
a <- data.frame(x=1:10, y=1, z=c(rnorm(8),-12,12))
get_col <- colorRamp(c("red", "white", "green")) # make fun to interpolate colors
quantiles <- (0:6) / 6 # how many quantiles we want to map
quantile.vals <- quantile(a$z, quantiles, names=F)# the values for each quantile
colours <- rgb(get_col(quantiles), max=255) # 7 evenly interpolated colors
val.remap <- (quantile.vals - min(a$z)) /
diff(range(a$z)) # The values corresponding to the quantiles
ggplot(a, aes(x=x,y=y,fill=z)) +
geom_bar(stat="identity") +
scale_fill_gradientn(
colours=colours,
values=val.remap,
breaks=quantile.vals,# Necessary to get legend values spread appropriately
guide="legend") # Necessary to get legend values spread appropriately
在这里,我们选择根据值的分布为值分配均匀的插值颜色。因此,如果一个值范围对应于分布的大部分,即使它实际上跨越了最小-最大范围的相对较小部分,它将获得更多的颜色分配。
如果要将特定颜色分配为零,可以通过编辑与 、 和 参数对应的向量colours来values实现breaks。如果您在零以上和零以下具有相同数量的值,则范围从微不足道,如果不是,则很烦人。
版本 w/0 设置为白色:
library(ggplot2)
a <- data.frame(x=1:10, y=1, z=c(rnorm(8), -12, 12))
splits <- 7 # should be odd number
mid.point <- 0
pos.vals <- a$z[a$z > mid.point]
neg.vals <- a$z[a$z < mid.point]
pos.quants <- quantile(c(mid.point, pos.vals), 0:((splits - 1) / 2) / ((splits - 1) / 2), names=F)
neg.quants <- quantile(c(mid.point, neg.vals), 0:((splits - 1) / 2) / ((splits - 1) / 2), names=F)
quants <- c(neg.quants, pos.quants[-1]) # drop of the mid-point from pos.quants since otherwise double counted
get_col <- colorRamp(c("red", "white", "green")) # make fun to interpolate colors
colours <- rgb(get_col(0:(splits - 1)/(splits - 1)), max=255) # 7 evenly interpolated colors
val.remap <- (quants - min(quants)) /
diff(range(quants)) # The values corresponding to the quantiles
ggplot(a, aes(x=x,y=y,fill=z)) +
geom_bar(stat="identity") +
scale_fill_gradientn(
colours=colours,
values=val.remap,
breaks=quants,
guide="legend")