【问题标题】:How to make a color scale with sharp transition in ggplot2如何在ggplot2中制作具有急剧过渡的色标
【发布时间】:2015-10-08 13:17:36
【问题描述】:

我正在尝试创建一个在某一点具有明显颜色过渡的色阶。我目前正在做的是:

test <- data.frame(x = c(1:20), y = seq(0.01, 0.2, by = 0.01))

cutoff <- 0.10

ggplot(data = test,
       aes(x = as.factor(x), y = y, fill = log(y), width = 1, binwidth = 0)) + 
 geom_bar(stat = "identity") +
 scale_fill_gradientn(colours = c("red", "red", "yellow", "green"), 
                      values = rescale(log(c(0.01, cutoff - 0.0000000000000001, cutoff, 0.2))), 
                      breaks = c(log(cutoff)), label = c(cutoff))

它正在产生我想要的情节。但是颜色条中的中断位置会因截止而有所不同。有时低于值,有时高于,有时就行。以下是一些具有不同截止值(0.05、0.06、0.1)的图:

我做错了什么?或者,有没有更好的方法来创建这样的色标?

【问题讨论】:

    标签: r ggplot2 colors


    【解决方案1】:

    您是否查看过scale_colour_stepsscale_colour_stepsn

    使用scale_colour_stepsn 中的n.break 选项,您应该能够指定所需的中断数并获得更清晰的过渡。

    一定要使用ggplot2 > 3.3.2

    【讨论】:

    • 我希望我能给这两个赞成票。谢谢!
    【解决方案2】:

    如果您仍然对此解决方案感兴趣,可以将guide = guide_colourbar(nbin = &lt;some arbitrarily large number&gt;) 添加到scale_fill_gradientn()。这会增加颜色条图例使用的 bin 数量,从而使过渡看起来更清晰。

    # illustration using nbin = 1000, & weighted colours below the cutoff
    plot.cutoff <- function(cutoff){
      p <- ggplot(data = test,
                  aes(x = as.factor(x), y = y, fill = log(y))) + 
        geom_col(width = 1) +
        scale_fill_gradientn(colours = c("red4", "red", "yellow", "green"), 
                             values = scales::rescale(log(c(0.01, cutoff - 0.0000000000000001, 
                                                            cutoff, 0.2))), 
                             breaks = c(log(cutoff)), 
                             label = c(cutoff),
                             guide = guide_colourbar(nbin = 1000))
      return(p)
    }
    
    cowplot::plot_grid(plot.cutoff(0.05),
                       plot.cutoff(0.06),
                       plot.cutoff(0.08),
                       plot.cutoff(0.1),
                       ncol = 2)
    

    (如果您发现上述在非常高分辨率下不够清晰,您还可以在guide_colourbar() 中设置raster = FALSE,它会关闭插值并改为绘制矩形。)

    【讨论】:

      【解决方案3】:

      认为使用scale_fill_gradientn 在连续色标中实现精确的离散截止点有点棘手。一个快速的替代方法是使用scale_fill_gradient,使用limits 设置截止值,并使用na.value 设置“越界”值的颜色。

      这是一个比你的问题稍微简单的例子:

      # some data
      df <- data.frame(x = factor(1:10), y = 1, z = 1:10)
      
      # a cutoff point
      lo <- 4 
      
      ggplot(df, aes(x = x, y = y, fill = z)) + 
        geom_bar(stat = "identity") +
        scale_fill_gradient(low = "yellow", high = "green",
                            limits = c(lo, max(df$z)), na.value = "red")
      

      如您所见,低于您的切割点的值不会出现在图例中,但人们可能会认为包含一大块红色是对“图例带宽”的浪费。您可以改为在图标题中添加对红色条的口头描述。


      您可能还希望区分低于下限和高于上限的值。例如,将“太低”的值设置为蓝色,将“太高的值”设置为红色。这里我使用findInterval 来区分低、中、高值。

      # some data
      set.seed(2)
      df <- data.frame(x = factor(1:10), y = 1, z = sample(1:10))
      
      # lower and upper limits
      lo <- 3
      hi <- 8
      
      # create a grouping variable based on the the break points
      df$grp <- findInterval(df$z, c(lo, hi), rightmost.closed = TRUE)
      
      ggplot(df, aes(x = x, y = y, fill = z)) + 
        geom_bar(stat = "identity") +
        scale_fill_gradient(low = "yellow", high = "green", limits = c(lo, hi), na.value = "red") +
        geom_bar(data = df[df$grp == 0, ], fill = "blue", stat = "identity")
      

      【讨论】:

      • 感谢您的建议!对于问题中的示例,这确实是一个很好的选择。但我在这里看到两个问题:1.低于截止值的值不能“加权”,例如colours = c("red4", "red", "yellow", "green") 在我的迷你示例 2 中。我认为图例中没有说明截止点这一事实使理解变得更加困难
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 2015-08-27
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 2019-06-04
      • 2018-11-14
      相关资源
      最近更新 更多