值的对称颜色条,但实际观察值的打印颜色条

问题描述 投票:0回答:1

假设我在 R

ggplot2
中创建了一个简单的热图。我需要对正空间和负空间使用某些预定义的颜色,其中 0 应该是白色,例如白色。是否可以绘制图块,使值根据正/负区域中相同的值范围采用颜色,但打印最终的颜色条仅显示值的实际范围?

Thisthis问题似乎相关,但他们关心的是在中点周围获得不对称的颜色条。

在左侧面板中,我有当前的颜色栏,在中间面板中,有预期的颜色栏,在右侧面板中,有链接问题的方法。在左侧面板中,值原则上是正确的,但打印了从 1.9 到 -1.9 的完整颜色条。右侧面板中的问题在于,它挤压了中点上方/下方范围内的完整颜色条,这意味着,例如,0.4 和 -0.4(左上角)具有不同的颜色。原则上colorbar的大小当然应该是一样的。

有没有一种方法可以理想地直接或间接(例如事后)实现这一目标?

example

这是对应的代码:

library(ggplot2)

df <- expand.grid(
  x = c(1, 2, 3),
  y = c(1, 2, 3),
  g = c("one", "two")
)

one <- c(1.90, 1.40, 1.10, 0.90, 0.80, 0.50, 0.40, 0.30, 0.20)
two <- c(1.90, 1.40, 1.10, 0.90, 0.80, -0.50, -0.40, -0.30, -0.20)
df$v <- c(one, two)

min_value <- min(df$v)
max_value <- max(df$v)
  
min_label <- round(min_value, 2)
max_label <- round(max_value, 2)
  
midpoint = 0

ggplot(df, aes(x = x, y = y, fill = v)) +
  facet_wrap(. ~ g, ncol = 2) +
  geom_tile(color = "black") +
  geom_text(aes(label = round(df$v, 2)), color = "red") +
  scale_y_discrete(expand = c(0,0)) +
  scale_x_discrete(expand = c(0,0)) +
  scale_fill_gradientn(
    colors = c(hcl.colors(5, "Inferno")[1:5], "white", hcl.colors(5, "Inferno")[5:1]),
    #values=c(1, (midpoint-min_value)/(max_value-min_value), 0), # uncomment for right heatmap and comment limits
    limits = c(-max_value, max_value),
    breaks = c(min_value, max_value),
    labels = c(min_label, max_label)
    ) +
  guides(
    fill = guide_colorbar(
      barheight = unit(5, "cm"),
      ticks.colour = "black",
      ticks.linewidth = 0.5,
      frame.colour = "black",
      frame.linewidth = 0.5     
    ))

r ggplot2 legend-properties
1个回答
0
投票

实现所需结果的一个选项是将

abs(v)
映射到
fill
上,并使用适当的
values=
向量,我使用
scales::rescale
:

library(ggplot2)

ggplot(df, aes(x = x, y = y, fill = abs(v))) +
  facet_wrap(. ~ g, ncol = 2) +
  geom_tile(color = "black") +
  geom_text(aes(label = round(v, 2)), color = "red") +
  scale_y_discrete(expand = c(0, 0)) +
  scale_x_discrete(expand = c(0, 0)) +
  scale_fill_gradientn(
    colors = c(hcl.colors(5, "Inferno")[1:5], "white", hcl.colors(5, "Inferno")[5:1]),
    values = scales::rescale(
      max_value * seq(-1, 1, length.out = 11),
      from = c(min_value, max_value)
    ),
    limits = c(min_value, max_value),
    breaks = c(min_value, max_value),
    labels = c(min_label, max_label)
  ) +
  guides(
    fill = guide_colorbar(
      barheight = unit(5, "cm"),
      ticks.colour = "black",
      ticks.linewidth = 0.5,
      frame.colour = "black",
      frame.linewidth = 0.5
    )
  )

© www.soinside.com 2019 - 2024. All rights reserved.