2017-06-19 158 views
1

我想绘制一些全局地图(光栅文件),并且在为我的数据设置好色彩比例时遇到了一些问题。我想要做的是使用不同的调色板绘制我的数据(例如cm.colors),并且我希望将这种比例的颜色“白色”与零值对齐,但不必在比例中设置对称值(即相同的负值和正值,即limits=c(-1,1))。此外,我想用相同的颜色绘制所有高于和/或低于某个值的值。ggplot2:通过设置连续色标来处理极端值

换句话说,如果我们假设我的地图的范围是-100到150,我想用一个与“0”值相对应的“白色”颜色的发散调色板绘制我的地图,例如低于-20和高于50以相同颜色绘制,即分别与调色板的负极值和正极值绘图。

在这里,我使用的时刻代码的例子:

ggplot(df, aes(y=Latitude, x=Longitude)) + 
    geom_raster(aes(fill=MAP)) + 
    coord_equal()+ 
    theme_gray() + 
    theme(panel.background = element_rect(fill = 'skyblue2', colour = 'black'), 
     panel.grid.major = element_blank(), 
     panel.grid.minor = element_blank(), 
     legend.position = "right", 
     legend.key = element_blank()) + 
    scale_fill_gradientn("MAP", limits=c(-0.5,1), colours=cm.colors(20)) 

回答

2

有简单的方法可以做到这一点,如事先截取你的数据,或者使用cut创建适当的标签离散箱。

require(dplyr) 
df %>% mutate(z2 = ifelse(z > 50, 50, ifelse(z < -20, -20, z))) %>% 
    ggplot(aes(x, y, fill = z2)) + geom_tile() + 
    scale_fill_gradient2(low = cm.colors(20)[1], high = cm.colors(20)[20]) 

enter image description here

df %>% mutate(z2 = cut(z, c(-Inf, seq(-20, 50, by = 10), Inf)), 
       z3 = as.numeric(z2)-3) %>% 
    {ggplot(., aes(x, y, fill = z3)) + geom_tile() + 
    scale_fill_gradient2(low = cm.colors(20)[1], high = cm.colors(20)[20], 
         breaks = unique(.$z3), labels = unique(.$z2))} 

enter image description here

但我想过这个任务之前,觉得不满意这一点。预截断不会留下漂亮的标签,并且cut选项总是很烦琐(特别是必须调整cut中的seq的参数并找出如何重新接收分档)。所以我试图定义一个可重用的转换,它可以为你截断和重新标记。

我还没有完全调试这个,我要出城,所以希望你或其他回答者可以采取一些措施。主要的问题似乎是边缘情况下的碰撞,所以有时候这些限制在视觉上重叠了预期的中断,以及一些格式化的意外行为。我只是使用一些虚拟数据来创建你想要的范围-100到150来测试它。

require(scales) 
trim_tails <- function(range = c(-Inf, Inf)) trans_new("trim_tails", 
       transform = function(x) { 
        force(range) 
        desired_breaks <- extended_breaks(n = 7)(x[x >= range[1] & x <= range[2]]) 
        break_increment <- diff(desired_breaks)[1] 
        x[x < range[1]] <- range[1] - break_increment 
        x[x > range[2]] <- range[2] + break_increment 
        x 
       }, 
       inverse = function(x) x, 

       breaks = function(x) { 
        force(range) 
        extended_breaks(n = 7)(x) 
       }, 
       format = function(x) { 
        force(range) 
        x[1] <- paste("<", range[1]) 
        x[length(x)] <- paste(">", range[2]) 
        x 
       }) 

ggplot(df, aes(x, y, fill = z)) + geom_tile() + 
    guides(fill = guide_colorbar(label.hjust = 1)) + 
    scale_fill_gradient2(low = cm.colors(20)[1], high = cm.colors(20)[20], 
         trans = trim_tails(range = c(-20,50))) 

enter image description here

用盒装的传说,而不是一个彩条同样适用,只是用... + guides(fill = guide_legend(label.hjust = 1, reverse = T)) + ...

enter image description here

+0

大,完全充实响应布赖恩。谢谢你。我现在不需要它,但我可以看到这个转换非常方便。 – SeldomSeenSlim