【问题标题】:Set custom non-linear scale bar with ggplot2使用 ggplot2 设置自定义非线性比例尺
【发布时间】:2018-11-04 17:29:57
【问题描述】:

我在网上没有找到任何答案。

我有这个情节:

a = data.frame(x=c(1,2,3,3,4,5,3,2,3,4), 
               y=c(1,2,3,6,4,5,3,2,3,2), 
               z=c(-4,-3.5,-2,-1,0,0.2,0.45,0.6,0.9,1))

ggplot()+
 geom_point(data=a, aes(x,y,fill=z),
            colour = "black", pch = 21, size = 3, stroke = 0.1)+
 scale_fill_gradientn(colors = c("blue","white","red"), 
                      breaks=c(-5,-4,-3,-2,-1,0,0.2,0.4,0.6,0.8,1),
                      limits=c(-5,1), 
                      guide = guide_colorbar(barwidth = 0.8, barheight = 18),
                      oob = scales::squish, 
                      trans = "identity")

这给了我这个比例尺:

当然这是我所期望的,因为比例是线性的,我定义了这些中断。

但是,我想知道如何获得如下所示的比例尺:

【问题讨论】:

  • 你对这个连续渐变的想法有多大的影响?如果您不介意将颜色切割成离散的中断,那将很容易做到(许多数据即极客认为无论如何都会使差异更加清晰)
  • 你能告诉我怎么做吗?

标签: r ggplot2 colors scale


【解决方案1】:

一种可能的解决方法是在将 z 值映射到 fill 参数之前重新缩放它们,以便这些值对应于线性颜色条,然后根据预先缩放的值标记图例:

a$z.rescaled <- ifelse(a$z < 0, a$z / 5, a$z)

> a
   x y     z z.rescaled
1  1 1 -4.00      -0.80
2  2 2 -3.50      -0.70
3  3 3 -2.00      -0.40
4  3 6 -1.00      -0.20
5  4 4  0.00       0.00
6  5 5  0.20       0.20
7  3 3  0.45       0.45
8  2 2  0.60       0.60
9  3 3  0.90       0.90
10 4 2  1.00       1.00

ggplot()+
  geom_point(data = a, 
             aes(x, y, fill = z.rescaled),
             colour = "black", pch = 21, size = 3, stroke = 0.1) +
  scale_fill_gradientn(name = "",
                       colors = c("blue", "white", "red"),
                       breaks = seq(-1, 1, 0.2),
                       labels = c(seq(-5, 0, 1), seq(0.2, 1, 0.2)),
                       limits = c(-1, 1),
                       guide = guide_colorbar(barwidth = 0.8, barheight = 18),
                       oob = scales::squish)

【讨论】:

  • 谢谢@Z.Lin,它工作得很好,我会用这个方法来制作我的真实情节。但是我想知道是否有一种方法可以在不创建支持变量的情况下达到相同的结果。
  • @AndreaNeri 我想不出任何不需要支持变量的方法。也许这里的其他人可以。 :)
【解决方案2】:

您可以使用cut 和手动定义的中断将连续的z 变量分解为离散变量,然后手动或使用预定义的调色板为其赋予发散色阶。

唯一棘手的部分是清理标签,我使用正则表达式模式从每个范围中提取最后一个数字。从技术上讲,这些标签并不完全准确,因为每种颜色代表一个值范围,而不仅仅是一个值,但我试图模仿你的例子。您可以跳过我在scale_color_brewer 中添加的标签函数,直接使用格式为 (0.2, 0.4] 的标签。

library(tidyverse)

a = data.frame(x=c(1,2,3,3,4,5,3,2,3,4), 
               y=c(1,2,3,6,4,5,3,2,3,2), 
               z=c(-4,-3.5,-2,-1,0,0.2,0.45,0.6,0.9,1))

a$brk <- cut(a$z, breaks = c(-6:0, seq(0.2, 1, by = 0.2)), include.lowest = T)

ggplot(a, aes(x = x, y = y, fill = brk)) +
  geom_point(shape = 21, size = 3, stroke = 0.1, color = "black") +
  scale_fill_brewer(palette = "RdBu", 
                    guide = guide_legend(reverse = T), 
                    direction = -1, drop = F, 
                    labels = function(x) str_extract(x, "(?<=,).+(?=\\])"))

一个问题是这给出了一个带有圆圈的图例,因为它采用geom_point 的形状。我搞砸了添加guide = guide_legend(override.aes = list(shape = 22)) 和其他形状来在那里制作正方形,但希望它看起来更像一个普通的传说。不过,你会从geom_col 的填充中得到一个更传统的图例,所以我使用了我从this answer 中学到的技巧来制作一个不可见的geom_col,然后关闭geom_point 的图例并且只使用geom_col创造的传奇。

ggplot(a, aes(x = x, y = y)) +
  geom_point(aes(fill = brk), shape = 21, size = 3, stroke = 0.1, color = "black", show.legend = F) +
  geom_col(aes(fill = brk), alpha = 0) +
  scale_fill_brewer(palette = "RdBu", 
                    guide = guide_legend(reverse = T, override.aes = list(alpha = 1)), 
                    direction = -1, drop = F, 
                    labels = function(x) str_extract(x, "(?<=,).+(?=\\])"))

reprex package (v0.2.0) 于 2018 年 5 月 25 日创建。

【讨论】:

  • 有一个标签参数 cut 可以保存正则表达式
  • @RichardTelford 我很困惑,我不认为cut 将正则表达式用作标签...你的意思是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
相关资源
最近更新 更多