如何在ggplot中手动设置分组颜色比例尺?

7

我正在尝试为 ggplot 的点图设置颜色刻度,标记不适宜、适宜、理想、适宜、不适宜的区域。在您的标准 ggplot 代码包装器内,我已经尝试使用 gradient2

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

gradient2

以及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))) +

渐变n

步骤n,

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

步骤n

分组

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"选项的帮助说明是:

返回一个连续的颜色比例尺的函数

但我无法理解和解释为什么需要创建一个连续颜色比例尺的函数,因为我只是想要说(例如)

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

我感觉可能是我快成功了,但是在某个步骤上有误解(也许是多个地方),或者我使用的方法不对,这与这三个函数都无关。

任何人能否提供建议?

谢谢大家!

编辑:根据威尔的建议更新:将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)) +

产生结果:

stepsn close

这很接近,但

A. colors向量与breaks不匹配

B. 颜色本身是混合而不是真实的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)

输出结果:

willexample

值正确,与颜色范围对齐(不知道为什么我的相同计算方法没有这个效果),但颜色是淡化的混合色 - 将该图片中的红色与第二张图片的彩虹尾端的红色进行比较。


1
如果您不需要颜色之间的渐变,可以考虑向数据框添加一列,以定义适宜性为不适宜、适宜、理想,并根据此因素进行着色。 - Will Oldham
漂亮、优雅的解决方案,威尔,不错。虽然我仍然对我尝试的那种解决方案感兴趣,但我想明天回来后我会采用你的解决方案。谢谢! - dez93_2000
2个回答

7

我正尝试着实现这个目标,并找到了一个使用 binned_scale 的方法,这也是 scale_color_stepsn 调用的方式。我将使用一个类似于 Will 的示例,希望你可以将其翻译成你的情况。

palette 参数仍然需要是一个函数,但你可以使用一个简单返回所需颜色的函数。在这里,我展示了你可以使用不规则的间隔,如果你想使用 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"

binned_scale_example


不错的东西@Goine0!我注意到你使用了4个断点+2个限制,而我使用了6个断点...我想知道这是否是使你的颜色不像我的那样混合的原因?下次回到我的主机时,我会尝试测试一下。干杯! - dez93_2000
不,颜色是因调色板而分配的。说实话,这有点像是一个hack,我认为它并不是用于这种用途的。六个断点在“show.limits = TRUE”时没有按预期工作,所以我必须单独指定限制。整个代码有些冗长,但确实能够完全达到你想要的效果。 - Goine0

4

看起来你离scale_color_stepsn很接近了,如果你将重新缩放的参数传递给breaks而不是scale_color_stepsn,它可能会起作用。我认为以下内容能实现你所希望的效果?

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 获取美观的图表,但是如你所见,此函数似乎会在断点处分配“纯”颜色,并将中间值的颜色合并(尽管我无法理解其他一些不寻常的颜色行为,例如颜色顺序错乱等)。如果您想要一个由纯红/黄/绿色组成的分段渐变色带,则我的原始评论可能是最佳方法-为数据框中的某个值分配颜色映射。上述代码中的图例具有均匀间隔的标签,如果您想要对断点进行标记,请在参数中添加 breaks = c(0, 22, 25, 26, 29, 40) ,但我发现以这种方式标记标签很难阅读。希望对您有所帮助。


再次感谢Will。第一段代码没有成功 - 所有的点都是绿色。也许我漏了什么,你是否应该在任何地方明确包括rescale?[编辑:对runif不需要。]我尝试了重新划分断点,但什么也没做。省略'values'很可能是导致图例消失的原因。gradientn看起来很接近,但颜色顺序相反(红色处于“理想”区域),并且在您的断点或重新缩放的原始值下也是如此,这似乎很奇怪。我与stepsn接近了,但奇怪的是颜色顺序很奇怪,我无法弄清楚为什么(在Q中更新)。 - dez93_2000
1
使用不同的方法更新了我的答案。希望能对您有所帮助。 - Will Oldham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接