用指定的分隔符覆盖两个 geom_contours 会显示不正确的线型

Overlaying two geom_contours with specified breaks shows incorrect line types

可重现的 R 代码

library(ggplot2)
library(metR)
v <- reshape2::melt(volcano)
g <- ggplot(v, aes(Var1, Var2)) +
  geom_contour(aes(z = value), color = "white", size = 1.25,
               breaks = c(100, 110, 120, 130, 140, 150, 160, 170, 180, 190)) +
  geom_contour(aes(z = value, linetype = ifelse(value <= 130, "solid", "dash")),
               color = "black", size = 0.45,
               breaks = c(100, 110, 120, 130, 140, 150, 160, 170, 180, 190),
               show.legend = F) +
  geom_text_contour(aes(z = value))
g

当我用白色背景覆盖一个 geom_contour 和另一个 geom_contourifelse 函数覆盖不同的线类型时,绘图过程显示破碎的等高线,接近指定的 ifelse 值为 130,如下图所示。

有人可以推荐解决方案吗?估计跟插值法有关

可重现的代码没有metR库(用于在上面的图上绘制等高线标签)

library(ggplot2)
v <- reshape2::melt(volcano)
g <- ggplot(v, aes(Var1, Var2)) +
  geom_contour(aes(z = value), color = "white", size = 1.25,
               breaks = c(100, 110, 120, 130, 140, 150, 160, 170, 180, 190)) +
  geom_contour(aes(z = value, linetype = ifelse(value <= 130, "solid", "dash")),
               color = "black", size = 0.45,
               breaks = c(100, 110, 120, 130, 140, 150, 160, 170, 180, 190),
               show.legend = F)
g

好吧,我觉得很蠢。一个简单的解决方法是简单地绘制两个具有指定值的单独 geom_contour,如下所示:

library(ggplot2)
v <- reshape2::melt(volcano)
g <- ggplot(v, aes(Var1, Var2)) +
  geom_contour(aes(z = value), color = "white", size = 1.25,
               breaks = c(100, 110, 120, 130, 140, 150, 160, 170, 180, 190)) +
  geom_contour(aes(z = value, linetype = "solid"),
               color = "black", size = 0.45,
               breaks = c(140, 150, 160, 170, 180, 190),
               show.legend = F) +
  geom_contour(aes(z = value, linetype = "dashed"),
               color = "black", size = 0.45,
               breaks = c(100, 110, 120, 130),
               show.legend = F)
g

但是,我仍然想知道是否有办法使用 ifelse 函数成功地做到这一点?

总之,用geom.contour功能是没有办法成功使用ifelse的。正确的用法是分别绘制两个等高线。请注意,该错误纯粹是由您的 ifelse 函数引起的,而不是由 叠加 两个图引起的,正如您在标题中假设的那样。

library(reshape2)
library(ggplot2)
v <- reshape2::melt(volcano)
g <- ggplot(v, aes(Var1, Var2)) +
  geom_contour(aes(z = value, linetype = "solid"),
               color = "black", size = 0.45,
               breaks = c(140, 150, 160, 170, 180, 190),
               show.legend = F) +
  geom_contour(aes(z = value, linetype = "dashed"),
               color = "black", size = 0.45,
               breaks = c(100, 110, 120, 130),
               show.legend = F)
g

see plot here

一般来说,ifelse 可以在 ggplot2 中使用来指定美学,但是,为了正确显示,要显示的值需要明确。

绘制等高线时 ggplot2 对数据进行分箱并在中断内生成连续的线条,然后使用指定的美学进行分类。您的 ifelse 操作会覆盖这些分类,导致可能的线条共享实线和虚线美学(未显示),或者仅部分 solid/dashed 美学(中断)。

如果您在 ifelse 中四舍五入您的数据(与您的垃圾箱对齐),这将变得更加明显。如您所见,中断的行不再是问题,但是,两者之间的较大差距 类 仍然存在。

library(reshape2)
library(ggplot2)
v <- reshape2::melt(volcano)
g <- ggplot(v, aes(Var1, Var2)) +
  geom_contour(aes(z = value, linetype = ifelse(round(value,-2) <= 130, "solid", "dash")),
               color = "black", size = 0.45,
               breaks = c(100, 110, 120, 130, 140, 150, 160, 170, 180, 190),
               show.legend = F)
g

see plot here