geom_ribbon() 形状美学导致不透明度差异

geom_ribbon() with shape aesthetic causes differences in opacity

geom_ribbon() 与形状美学一起使用时,阴影区域的不透明度似乎有所不同,从而在该区域创建块。 我重新创建了问题,我发现这些不透明度变化仅在包含形状美学时才会出现。

数据设置:

alpha <- c("A","B","C","D", "E", "F", "G")
percent <- c(0.012, -0.02, 0.015, -0.01, 0.89, 0.12, -0.25)
flow <- c(-5, 2, -3, 3, 1, 4, -2)
shape <- c("D", "D", "L", "L", "L", "D", "L")

df <- data.frame(alpha,percent,flow, shape)

x_min = min(df$percent)
x_min = round(x_min/0.01)*0.01 - 0.01

x_max = max(df$percent)
x_max = round(x_max/0.01)*0.01 + 0.01

y_min = min(df$flow)
y_min = round(y_min)

y_max = max(df$flow)
y_max = round(y_max)

n_row = nrow(df)

没有形状美感的图表,geom_ribbon() 有效:

df %>%
  ggplot(aes(x = percent, y = flow, label = alpha)) + 
  geom_point() + 
  geom_text_repel(show.legend = FALSE, size = 3) +
  scale_size_continuous(labels = scales::percent) + 
  theme_bw() + 
  scale_x_continuous(labels = scales::percent_format(accuracy = 0.1L)) + 
  scale_y_continuous(labels = scales::dollar_format(negative_parens = TRUE, suffix = "m")) + 
  geom_ribbon(aes(x = seq(x_min, x_max + 0.01, length.out = n_row), ymin = 0, ymax = y_max), alpha = 0.04, linetype = 0, show.legend = FALSE, fill = "green") + 
  geom_ribbon(aes(x = seq(x_min, x_max + 0.01, length.out = n_row), ymin = y_min, ymax = 0), alpha = 0.04, linetype = 0, show.legend = FALSE, fill = "red")

具有形状美感的图表,geom_ribbon() 似乎不起作用:

df %>%
  ggplot(aes(x = percent, y = flow, label = alpha, shape = shape)) + 
  geom_point() + 
  geom_text_repel(show.legend = FALSE, size = 3) +
  scale_size_continuous(labels = scales::percent) + 
  theme_bw() + 
  scale_x_continuous(labels = scales::percent_format(accuracy = 0.1L)) + 
  scale_y_continuous(labels = scales::dollar_format(negative_parens = TRUE, suffix = "m")) + 
  geom_ribbon(aes(x = seq(x_min, x_max + 0.01, length.out = n_row), ymin = 0, ymax = y_max), alpha = 0.04, linetype = 0, show.legend = FALSE, fill = "green") + 
  geom_ribbon(aes(x = seq(x_min, x_max + 0.01, length.out = n_row), ymin = y_min, ymax = 0), alpha = 0.04, linetype = 0, show.legend = FALSE, fill = "red")

问题是某种过度绘制以及您通过 geom_ribbon 添加背景填充的方式。基本上,通过添加 shape 作为全局美学,您的数据会被分组,并且您的色带会被多次绘制,每个组一次。要解决此问题,请将 shape 移动到 geom_point:

中,使其成为本地 aes
library(ggplot2)

ggplot(df, aes(x = percent, y = flow, label = alpha)) + 
  geom_point(aes(shape = shape)) + 
  ggrepel::geom_text_repel(show.legend = FALSE, size = 3) +
  scale_size_continuous(labels = scales::percent) + 
  theme_bw() + 
  scale_x_continuous(labels = scales::percent_format(accuracy = 0.1L)) + 
  scale_y_continuous(labels = scales::dollar_format(negative_parens = TRUE, suffix = "m")) + 
  geom_ribbon(aes(x = seq(x_min, x_max + 0.01, length.out = n_row), ymin = 0, ymax = y_max), alpha = 0.04, linetype = 0, show.legend = FALSE, fill = "green") + 
  geom_ribbon(aes(x = seq(x_min, x_max + 0.01, length.out = n_row), ymin = y_min, ymax = 0), alpha = 0.04, linetype = 0, show.legend = FALSE, fill = "red")

但是,在我看来,如果不使用 geom_ribbon,您可以通过 annotate 添加背景矩形,从而更容易获得结果并且更不容易出错,这取决于您想要的结果甚至不需要计算最小值和最大值。相反,您可以简单地使用 -InfInf:

ggplot(df, aes(x = percent, y = flow, label = alpha, shape = shape)) + 
  geom_point() + 
  ggrepel::geom_text_repel(show.legend = FALSE, size = 3) +
  scale_size_continuous(labels = scales::percent) + 
  theme_bw() + 
  scale_x_continuous(labels = scales::percent_format(accuracy = 0.1)) + 
  scale_y_continuous(labels = scales::dollar_format(negative_parens = TRUE, suffix = "m")) + 
  annotate(geom = "rect", xmin = -Inf, xmax = Inf, ymin = 0, ymax = Inf, alpha = 0.04, fill = "green") + 
  annotate(geom = "rect", xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = 0, alpha = 0.04, fill = "red")