R:如何在 ggplot 中手动设置分箱色标?

R: How to manually set binned colour scale in ggplot?

我正在尝试为 ggplot 点图设置色标,划分区域:不合适、合适、理想、合适、不合适。在您的标准 ggplot 代码包装器中,我尝试了 gradient2

scale_colour_gradient2(low = "grey",
                       mid = "red",
                       high = "grey",
                       midpoint = 25) +

gradientn

scale_colour_gradientn(colours = rev(rainbow(5)),
                       breaks = seq(0, 30, by = 5),
                       limits = c(0, 30),
                       labels = as.character(seq(0, 30, by = 5))) +

stepsn,

scale_colour_stepsn(colours = c("grey", "blue", "red", "blue", "grey"),
                    values = scales::rescale(c(0, 22, 25, 26, 29, 40))) +

binned

scale_colour_binned(type = "viridis",
                      breaks = c(22, 25, 26, 29),
                      limits = c(0, 40),
                      guide = guide_coloursteps(even.steps = FALSE,
                                                show.limits = TRUE)) +

binned 是最接近的,但我不知道如何指定我想要的 5 种颜色(即,不是 viridis)。我大概想要的 'type' 的帮助选项是:

A function that returns a continuous colour scale

但我无法在心理上平方 how/why 我需要创建一个函数来创建连续的颜色比例,因为我只想说(例如)

c("red", "yellow", "green", "yellow", "red")

我觉得要么我很接近并且只是误解了某处(可能是多个地方)的步骤,要么我使用了错误的方法,这是这 3 个函数中的 none。

有没有人可以提供建议?

谢谢大家!

编辑:根据 Will 的建议进行更新:保持 geom_point 调用中的值不变,即

geom_point(aes(colour = MeanETemp24hU2M), size = 0.5) +

(而不是将它们重新缩放为 0:1),以下代码:

scale_colour_stepsn(colours = c("red", "yellow", "green", "yellow", "red"),
                      limits = c(0, 40),
                      guide = guide_coloursteps(even.steps = FALSE,
                                                show.limits = TRUE),
                      breaks = c(0, 22, 25, 26, 29, 40)) +

产生:

接近但是

一个。 colours 向量与 breaks bins

不匹配

乙。颜色本身是混合色,而不是真正的 R 色。使用对 Will 示例的修改:

x <- 1:100
y <- runif(100) * 100
tibble(x, y) %>% 
  ggplot() +
  aes(x = x, y = y, color = y) +
  geom_point() +
  scale_color_stepsn(
    colours = c("red", "yellow", "green", "yellow", "red"),
    breaks = c(0, 0.2, 0.4, 0.6, 0.8, 1) * 100)

产生:

这些值是正确的并且正确地与颜色箱对齐(IDK 为什么我的没有给出相同的配方),但颜色是稀释的混合 - 比较该图像中的红色与图像末尾的红色第二张图片中的彩虹。

看起来您已经接近 scale_color_stepsn,如果您将重新缩放参数传递给 breaks,它可能会起作用。我认为以下内容符合您的期望?

library(tidyverse)

x <- 1:100
y <- runif(100)
tibble(x, y) %>% 
  ggplot() +
  aes(x = x, y = y, color = y) +
  geom_point() +
  scale_color_stepsn(
    colours = c("red", "yellow", "green", "yellow", "red"),
    breaks = c(0, 0.2, 0.4, 0.6, 0.8, 1)
  )

可以代替scale_color_gradientn,漂亮多了!

scale_color_gradientn(
    colours = c("red", "yellow", "green", "yellow", "red"),
    breaks = c(0, 0.2, 0.4, 0.6, 0.8, 1)

编辑:

重新缩放问题肯定是一个问题。我认为此解决方案适用于 scales_color_gradientn。请注意,我稍微更改了测试数据框。

library(tidyverse)

x <- seq(0, 40, 0.25)
y <- seq(0, 40, 0.25)
tibble(x, y) %>% 
  ggplot() +
  aes(x = x, y = y, color = y) +
  geom_point() +
  scale_color_gradientn(
    colours = c("red", "yellow", "green", "yellow", "red"),
    values = scales::rescale(c(0, 22, 25, 26, 29, 40))
  )

我尝试了几次 scales_color_stepsn 来获得一些不错的东西,但是正如您所看到的,这个函数似乎在中断处分配了“纯”颜色并合并了它们之间值的颜色(我是但能够理解颜色乱序等其他一些异常行为)。我想如果你想要一个纯 red/yellow/green 颜色的阶梯渐变,我原来的评论可能是最好的方法——在你的数据框中分配一个值来将颜色映射到。上面代码中的图例具有均匀间隔的标签,如果你想标记中断,请将 breaks = c(0, 22, 25, 26, 29, 40) 添加到参数中,尽管我发现这样很难阅读标签。 HTH.

我正试图做到这一点,并找到了 binned_scale 的方法,这就是 scale_color_stepsn 调用的方法。我将使用与 Will 类似的示例,希望您能将其转化为您的案例。

palette 参数仍然需要是一个函数,但您可以使用一个简单地 returns 您想要的颜色的函数。在这里我展示了你可以使用不规则的中断,如果你想使用 show.limits = TRUE 则单独指定限制(否则它会在你的数据集中显示限制)。

x <- 1:100
y <- runif(100) * 100
tib <- tibble(x, y)

ggplot(tib, aes(x = x, y = y, color = y)) +
  geom_point() +
  binned_scale(aesthetics = "color",
               scale_name = "stepsn", 
               palette = function(x) c("red", "yellow", "green", "yellow", "red"),
               breaks = c(5, 10, 25, 60),
               limits = c(0, 100),
               show.limits = TRUE, 
               guide = "colorsteps"
  )

此处,需要 guide = "colorsteps" 才能在图例中填充方块。如果你想要图例中的比例条与 even.steps = FALSE 一样,那么你需要使用 guide = "colorbar" 代替。