【发布时间】:2019-01-07 01:37:39
【问题描述】:
这里最重要的工作是将geom_line 的图例形状更改为geom_point“点”,但在图中保留geom_line。如果有人可以演示如何创建一个更简洁的 geom_line2() 函数(见下文),该函数在图例中显示 geom_point“点”对象,我将不胜感激。
我知道可以将geom_point 分层并为geom_line 影响guides(color = FALSE)。但是,我想了解如何在ggproto 代码中执行此操作。我也知道geom_point 可以覆盖图例形状,但这种方法不适用于geom_line。
我尝试修改 GeomPath 对象以将 draw_key = draw_key_path 更改为 draw_key = draw_key_point,但由于多种原因失败了。
我还认为使用guides(color = guide_geom()) 可能能够达到预期的效果,但正如广泛宣传的那样,这是一个未记录的功能。看了 GitHub 上的源代码,还是没进步。
底部的代码 sn-p 产生了想要的效果,但是很hacky。
# this is the default
library(tidyverse)
library(grid)
mydf <- tibble(month = rep(seq(1, 10, 1), 4),
olympian = sort(rep(c("apollo", "jove", "mercury", "minerva"), 10)),
weight = c(seq(51, 60, 1), seq(60, 78, 2),
seq(69.5, 56, -1.5), seq(55, 46, -1)))
ggplot(mydf, aes(month, weight, color = olympian)) +
geom_line(size = 1) +
theme_light() +
labs(title = "Default geom_line legend shape")
# here is what worked to achieve the effect
GeomLine2 <- GeomPath
GeomLine2$draw_key <- function(data, params, size) {
data$linetype[is.na(data$linetype)] <- 0
segmentsGrob(0.5, 0.5, 0.5, 0.5, # NOTE CHG HERE
gp = gpar(
col = alpha(data$colour, data$alpha),
lwd = 5, # NOTE CHG HERE
lty = data$linetype,
lineend = "round" # NOTE CHG HERE
),
arrow = params$arrow
)
}
geom_line2 <- function (mapping = NULL, data = NULL,
stat = "identity", position = "identity",
na.rm = FALSE, show.legend = NA, inherit.aes = TRUE,
...)
{
layer(data = data, mapping = mapping, stat = stat, geom = GeomLine2,
position = position, show.legend = show.legend, inherit.aes =
inherit.aes,
params = list(na.rm = na.rm, ...))
}
ggplot(mydf, aes(month, weight, color = olympian)) +
geom_line2(size = 1) +
theme_light() +
labs(subtitle = "Hacked geom_line legend shape")
此代码还会产生不良副作用,即将所有未来对ggplot2::geom_line 的调用设置为相同的图例效果。
PS ... this answer 会有所帮助,但它适用于旧的ggplot2
【问题讨论】:
-
修改
GeomPath会如何产生问题?我曾想过在environment(GeomPath$draw_key)$f <- [your customised function above]和environment(GeomPath$draw_key)$f <- draw_key_path之间切换可以让您在两种图例类型之间切换? -
我会给出重点,因为我同意下面的 dww。 . .通过从
GeomPoint移植到draw_key进行更改将引发由于未指定大小和笔划而导致的错误。此外,如果没有像keep_mid_true这样的函数,自定义函数也会失败。最后,奇怪的曲折(比如找到Kmisc::dapply)在这个过程中引发了一致的扳手。