R ggplot:传说中的“交叉效应”(不会随着 show.legend = NA 而消失)
Posted
技术标签:
【中文标题】R ggplot:传说中的“交叉效应”(不会随着 show.legend = NA 而消失)【英文标题】:R ggplot: "cross effect" in legend (not going away with show.legend = NA) 【发布时间】:2019-10-27 00:04:22 【问题描述】:以下代码会导致图例中出现不需要的交叉效果。
ggplot() +
geom_vline(aes(xintercept=1,colour="vertical"), show.legend = NA) +
geom_hline(aes(yintercept=1,colour="horizontal"), show.legend = NA)
我读过几篇帖子说添加show.legend = NA
可以使这种效果消失,但这不适用于我的情况。
编辑: 为避免混淆,我不希望传说消失!我只是想让传说中的“十字架”消失,所以它应该显示如下项目:
和
【问题讨论】:
试试show.legend = FALSE
抱歉,我不想让传奇消失。我只是想让传说中的“十字架”消失。请参阅上面的编辑。
【参考方案1】:
我同意修复图例可能会很棘手。对于此示例,只需将 show.legend = FALSE
放在您不想要的 ONE 行。
library(ggplot2)
ggplot() +
geom_vline(aes(xintercept=1,colour="vertical"), show.legend = F) +
geom_hline(aes(yintercept=1,colour="horizontal"))
好的,这是尝试 2。它很丑;它将两个传说塞进一个情节。它看起来非常接近你想要的。
library(ggplot2)
p1 <- ggplot() +
geom_vline(aes(xintercept=1,colour="vertical"))+
scale_color_manual(values = "#619CFF")
p2 <- ggplot()+
geom_hline(aes(yintercept=1,colour="horizontal"))
l1 <- cowplot::get_legend(p1)
l2 <- cowplot::get_legend(p2)
p3 <- ggplot() +
geom_vline(aes(xintercept=1,colour="vertical")) +
geom_hline(aes(yintercept=1,colour="horizontal"))+
theme(legend.position = "none")
l3 <- cowplot::plot_grid(l1, l2, ncol = 1, align = "v")
cowplot::plot_grid(p3, l3, nrow = 1, align = "h", rel_widths = c(1, 0.2))
【讨论】:
刚刚注意到你想要一个垂直和一个水平。我将编辑我的答案。 嘿,我知道只有第一次使用“show.legend = F”才有效,但我自己并没有想到这一点。我很想知道你将如何获得一个水平和一个垂直的! 谢谢!我了解将 p3 和 l3 彼此相邻绘制的技巧。但最终我使用了你的第一个解决方案。它非常简单/健壮,并且在图例中垂直线的方向是水平的并不是真正的问题。【参考方案2】:如果您愿意深入了解底层网格(这总是很有趣),您可以手动删除指南中的垂直/水平条。
library(ggplot2)
library(grid)
library(gtable)
p <- ggplot() +
geom_vline(aes(xintercept = 1, color = "vertical")) +
geom_hline(aes(yintercept = 1, color = "horizontal"))
## First we create a gr(aphical)ob(ject) from the ggplot
g <- ggplotGrob(p)
## then we have to find out which child grob represents the legend
## the grob with the name "guide-box" is the one we are looking for
guide <- which(g$layout$name == "guide-box")
## the legend consists of guides and the background, go for the guides
guide_lines <- which(g$grobs[[guide]]$layout$name == "guides")
## the guides contain a lot of different grobs
## if you look at g$grobs[[guide]]$grobs[[guide_lines]] you will see
## 4 segments representing the 4 lines, these are at position 4-5 and 7-8
## segments at 4 and 7 are the vertical lines and 5 and 8 the horizontal lines
## NOTE: this you have to find out "manually", if you change the order in your
## ggplot the positions will be exactly switched
## one could write e function which checks whether a line is horizontal
## or vertical but this is most likely an overkill if this is for a
## single plot
## we can use gtable_filter to remove the unwanted lines
## it requires a regular expression formed by the names of the grobs to filter out
remove_pattern <- paste(g$grobs[[guide]]$grobs[[guide_lines]]$layout$name[c(4, 8)],
collapse = "|")
## write back the filtered gtable
g$grobs[[guide]]$grobs[[guide_lines]] <-
gtable_filter(g$grobs[[guide]]$grobs[[guide_lines]],
remove_pattern,
invert = TRUE)
## draw the grid
grid.draw(g)
【讨论】:
@thotal。我安装了最新版本的gtable
,现在一切正常。
令人印象深刻的答案和很好的解释。你能指出关于grobs
的文献吗?
R Graphics 作者 Paul Murrell 作为参考书。不过,我通过 SO 和其他在线资源了解了网格。一旦你有了关于图形对象的想法,就会有很多str(.)
来检查结构。根据我的经验,代码不是很稳定,因为ggplot
的新迭代会移动到其他位置,您必须再次开始寻宝游戏。但为了快速修复,这是我通常的工作
我会查的。谢谢。
@thotal Wonderfull 解决方案!最后,我使用了下面建议的更简单的解决方案,但我会记住,如果我想做得更好,这也是可能的。【参考方案3】:
geom_vline
似乎存在一个已知错误
https://github.com/tidyverse/ggplot2/issues/1267
以那个 URL 上的代码为灵感,我想出了一些使用 geom_linerange
的东西
thresholds <- data.frame(colour = "vertical", x = 1, ymin = 0.950, ymax = 1.050)
ggplot() +
geom_hline(aes(yintercept = 1, colour = "horizontal"), show.legend = NA) +
geom_linerange(data = thresholds,
mapping = aes(x = x, ymin = ymin, ymax = ymax, linetype = colour)) +
theme(legend.title = element_blank())
产生以下情节
【讨论】:
对不起,我不希望传奇消失。我只是想让传说中的“十字架”消失。请参阅上面的编辑。 @Frank 根据您的评论,我完全重写了我的答案。请看一下 谢谢。我还读到这实际上是一个错误。很高兴知道我使用 geom_linerange 解决了这个问题!以上是关于R ggplot:传说中的“交叉效应”(不会随着 show.legend = NA 而消失)的主要内容,如果未能解决你的问题,请参考以下文章