【问题标题】:ggplot2: dealing with extremes values by setting a continuous color scaleggplot2:通过设置连续色标来处理极值
【发布时间】:2017-11-21 12:37:51
【问题描述】:

我正在尝试绘制一些全局地图(光栅文件),但在为我的数据设置良好的色标时遇到了一些问题。我想做的是使用发散调色板(例如cm.colors)绘制我的数据,并且我想将这种比例的颜色“白色”与零值居中,但不必在比例(即负和正的值相同,即limits=c(-1,1))。此外,我想用相同的颜色绘制高于和/或低于某个值的所有值。

换句话说,如果我们假设我的地图的范围是 -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))

【问题讨论】:

    标签: r ggplot2 colors raster color-palette


    【解决方案1】:

    有一些简单的方法可以做到这一点,例如预先截断您的数据,或使用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])
    

    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))}
    

    但我之前也想过这个任务,对此感到不满意。预截断不会留下漂亮的标签,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)))
    

    也可以使用盒装图例而不是颜色条,只需使用 ... + guides(fill = guide_legend(label.hjust = 1, reverse = T)) + ...

    【讨论】:

    • 很好,完全充实的回应布赖恩。谢谢你。我现在不需要它,但我可以看到转换非常方便。
    猜你喜欢
    • 1970-01-01
    • 2010-11-29
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多