【问题标题】:buffer areas around lines ggplot2线周围的缓冲区ggplot2
【发布时间】:2016-11-14 12:24:53
【问题描述】:

我想要一个图表,它作为一年中的一天的函数,在 x 和 y 轴上从 0 -> 100% 前进(其中每个轴都是一个单独的指标)。根据数据相对于一年中某一天的位置,我想说明这是好是坏。很简单,我可以这样展示:

因此,上图显示我们处于良好状态,因为“尖端”(最暗的最大点)已超过 50% 标记(假设我们全年为 50%)。但我想在水平线和垂直线周围添加渐变线以显示更多细微差别。这是对这些区域的解释(第一张图是解释……第二张是我想在 ggplot 中显示的方式……完全填充区域。

这是我在 ggplot 中的进展:

我遇到的问题:

  1. 由于某种原因,垂直渐变不接受 alpha 参数
  2. 我不能分配两个不同的渐变,一旦我定义了渐变,它就会应用于垂直和水平的渐变。
  3. 这看起来很糟糕。我应该遵循更好的方法吗?

问题 1-2 是否可以解决?如果有人有更好的方法不使用geom_line,请随时提出建议。

编辑:随着线条移动,渐变也会移动,因此静态背景在这里不起作用。

代码如下:

dff <- data.frame(x = 1:60+(runif(n = 60,-2,2)),
                  y = 1:60+(runif(n = 60,-2,2)),
                  z = 1:60)

dfgrad <- data.frame(static = c(rep(50,1000)), line = seq(0,100,length.out=100))

## To see the gradientlines thinner, change the size on the geom_line  to like 200

ggplot(dff,aes(x,y)) +
  geom_line(data = dfgrad, aes(x=static, y=line, color=line),size=1000,alpha=0.5) +
  geom_line(data = dfgrad, aes(x=line, y=static, color=line),size=1000,alpha=0.5) +
  scale_colour_gradientn( colours = c( "yellow", "darkgreen","darkred"),
                          breaks  = c( 0, 3, 100),
                          limits  = c( 0,100)) +
  geom_hline(yintercept = 50, linetype="dashed") +
  geom_vline(xintercept = 50, linetype="dashed") +
  geom_point(aes(alpha=dff$z,size= (dff$z))) +
  theme(legend.position="none") +
  scale_x_continuous(expand = c(0, 0)) + scale_y_continuous(expand = c(0, 0))

最终编辑:提交的答案是正确的,但是为了根据“今天”行更改渐变,我不得不再弄乱一点......所以我将它粘贴在这里以防它对任何人有用:

g1 <- colorRampPalette(c("darkgreen", "darkgreen","red"))(20) %>%
  alpha(0.3) %>% matrix(ncol=1) %>%  # up and down gradient
  rasterGrob(width = 1, height = 1)  # full-size (control it by ggplot2)

g2 <- colorRampPalette(c("yellow", "darkgreen","red"))(20) %>% 
  alpha(0.3) %>% matrix(nrow=1) %>%  # left and right gradient
  rasterGrob(width = 1, height = 1)

timeOfYear <- 5
maxx <- max(timeOfYear,(100-timeOfYear))

ggplot(dff,aes(x,y)) +
  annotation_custom(g1, xmin = timeOfYear-maxx, xmax = timeOfYear+maxx, ymin = timeOfYear-maxx, ymax = timeOfYear+maxx) +
  annotation_custom(g2, xmin = timeOfYear-maxx, xmax = timeOfYear+maxx, ymin = timeOfYear-maxx, ymax = timeOfYear+maxx) +
  # annotation_custom(g1, xmin = 35, xmax = 65, ymin = -3, ymax = 100) +
  # annotation_custom(g2, xmin = -3, xmax = 100, ymin = 35, ymax = 65) +
  geom_hline(yintercept = timeOfYear, linetype="dashed") +
  geom_vline(xintercept = timeOfYear, linetype="dashed") +
  geom_point(aes(alpha=dff$z,size= (dff$z))) +
  theme(legend.position="none") +
  coord_cartesian(xlim = c(0, 100), ylim = c(0, 100), expand = F)

【问题讨论】:

    标签: r ggplot2 gradient


    【解决方案1】:

    如果我是你,我会使用 grid 包制作矩形,然后使用 annotation_custom() 将它们放在图表上。 (你的问题1是因为覆盖,试试alpha=0.05

    这是我的例子:

    library(ggplot2); library(grid); library(dplyr)
    
    g1 <- colorRampPalette(c("yellow", "darkgreen","darkred"))(20) %>%
      alpha(0.5) %>% matrix(ncol = 1) %>%   # up and down gradient
      rasterGrob(width = 1, height = 1)     # full-size (control it by ggplot2)
    
    g2 <- colorRampPalette(c("cyan", "darkgreen","darkblue"))(20) %>% 
      alpha(0.5) %>% matrix(nrow = 1) %>%   # left and right gradient
      rasterGrob(width = 1, height = 1)
    
    ggplot(dff,aes(x,y)) +
      annotation_custom(g1, xmin = 35, xmax = 65, ymin = -3, ymax = 100) + 
      annotation_custom(g2, xmin = -3, xmax = 100, ymin = 35, ymax = 65) + 
      geom_hline(yintercept = 50, linetype="dashed") +
      geom_vline(xintercept = 50, linetype="dashed") +
      geom_point(aes(alpha=dff$z,size= (dff$z))) +
      theme(legend.position="none") +
      coord_cartesian(xlim = c(-3, 100), ylim = c(-3, 100), expand = F)
    


    [已编辑]

    这是我为每个 timeOfYear 保持相同程度梯度的方法(我参考了@Amit Kohli 的代码)(左图是概念);

     # I added both limits colors as outside colors 
     # to avoid that graph becomes almost green when timeOfYear is about 50.
    g1.2 <- c(rep("yellow", 5), colorRampPalette(c("yellow", "darkgreen","red"))(20), rep("red", 5)) %>%
      rev() %>% alpha(0.3) %>% matrix(ncol=1) %>% rasterGrob(width = 1, height = 1)
    
    g2.2 <- c(rep("yellow", 5), colorRampPalette(c("yellow", "darkgreen","red"))(20), rep("red", 5)) %>%
      alpha(0.3) %>% matrix(nrow=1) %>% rasterGrob(width = 1, height = 1)
    
    timeOfYear <- 5
    
    ggplot(dff, aes(x, y)) +
      annotation_custom(g1.2, timeOfYear - 100, timeOfYear + 100, timeOfYear - 100, timeOfYear + 100) +
      annotation_custom(g2.2, timeOfYear - 100, timeOfYear + 100, timeOfYear - 100, timeOfYear + 100) + 
      geom_hline(yintercept = timeOfYear, linetype="dashed") +
      geom_vline(xintercept = timeOfYear, linetype="dashed") +
      geom_point(aes(alpha=dff$z,size= (dff$z))) +
      theme(legend.position="none") +
      coord_cartesian(xlim = c(0, 100), ylim = c(0, 100), expand = F)
    

    如果您需要,SpaDES::divergentColors() 会为您提供具有非对称范围的颜色矢量(可能某些软件包具有类似的功能)。

    library(SpaDES)
    
    timeOfYear <- 5
    
    # ?divergentColors(start.color, end.color, min.value, max.value, mid.value = 0, mid.color = "white")    
       # It makes a vector of colors (length: max.value - min.value) 
       # and you can define mid.color's val (i.e., position)
    
    g3 <- divergentColors("yellow", "red", 0, 100, timeOfYear, mid.color = "darkgreen") %>% 
      rev() %>% alpha(0.3) %>% matrix(ncol = 1) %>% rasterGrob(width = 1, height = 1)
    
    g4 <- divergentColors("yellow", "red", 0, 100, timeOfYear, mid.color = "darkgreen") %>% 
      alpha(0.3) %>% matrix(nrow = 1) %>% rasterGrob(width = 1, height = 1)
    
    ggplot(dff,aes(x,y)) +
      annotation_custom(g3, xmin = 0, xmax = 100, ymin = 0, ymax = 90) +
      annotation_custom(g4, xmin = 0, xmax = 90, ymin = 0, ymax = 100) + 
      geom_hline(yintercept = timeOfYear, linetype="dashed") +
      geom_vline(xintercept = timeOfYear, linetype="dashed") +
      geom_point(aes(alpha=dff$z,size= (dff$z))) +
      theme(legend.position="none") +
      coord_cartesian(xlim = c(0, 100), ylim = c(0, 100), expand = F)
    

    【讨论】:

    • 这个方法也比我的方法快得多,而且渲染得稍微漂亮一些。 Alpha = 0.3 看起来不错。谢谢,不知道rasterGrob
    • 检查我所做的最终编辑......当一天不是 50% 时,将网格外推到整个 0-100 范围是很棘手的......检查我根据你的实现的解决方案。它起作用了……我们从 50% 得到的越远,它就会被冲掉……但它会起作用的。
    • @AmitKohli;抱歉,我没注意。我编辑了。
    • 是的,divergentcolor 正是这样做的。我将不得不尝试我的“淘汰”解决方案与divergentcolor,看看差异有多大。这真的很有趣......我在这个解决方案上搞砸了一段时间......无法计算出数学......把它写在一张纸上,不到一分钟。还没有数字化!
    猜你喜欢
    • 2022-10-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 2022-09-22
    • 2018-04-30
    • 2018-05-27
    • 1970-01-01
    • 2018-11-07
    相关资源
    最近更新 更多