使用循环在构面中创建多个 geom_hline 对象时,如何有效地创建手动图例?
How can I efficiently create a manual legend when using a loop to create multiple geom_hline objects in a facet?
我编写了以下示例来说明我的问题。
我想为我绘制的每个 geom_hline 创建我自己的自定义图例和配色方案。我可以通过使用这个答案 Construct a manual legend for a complicated plot.
来实现这一点
但是,我正在创建一个函数,它将在绘图上创建任意数量的水平线,并带有一个循环。这意味着我需要动态地将变量提供给 aes_string 函数。然而,
aes_string(yintercept = colname, colour = colname)
不起作用。因为我会得到以下错误'geom_hline Error: Discrete value supplied to continuous scale'
。
这导致我创建了以下解决方案,其中涉及为我希望绘制的每一行创建一个额外的列,其中包含一个可以由 scale_colour_manual 中的向量获取的名称。我觉得这很麻烦而且效率低下。
这按预期工作,但我有 2 个问题:
为什么 aes_string(yintercept = colname, colour = colname_colour)
有效而 aes_string(yintercept = colname, colour = colname)
无效。
必须有一种更有效的方法来实现我得到的输出,我错过了什么?
示例代码输出:http://imgur.com/a/dvzAM
mean_wt <- data.frame(cyl = c(4, 6, 8)
, wt = c(2.28, 3.11, 4.00)
, wt2 = c(3.28, 4.11, 5.00)
, wt_col = c("a", "a", "a")
, wt_col2 = c("b", "b", "b"))
hline_listA <- list()
for(i in 2:3){
colname <- mean_wt[,i]
colname_colour <- mean_wt[,i+2]
grob <- geom_hline(data =mean_wt
, aes_string(yintercept = colname, colour = colname_colour) )
hline_listA[[i-1]] <- grob
}
ggplot() +
geom_point(data = mtcars, aes(mpg, wt)) +
hline_listA +
facet_wrap(~ cyl, scales = "free", nrow = 1) +
scale_colour_manual(name = "legend", values = c(
"a" = "seagreen1"
, "b" = "darkorange" ))
我无法想象我会在 ggplot 中使用循环做任何事情的情况。实现你想要的通常方法是以 ggplot 可以使用它的方式调整数据框。这是一个更短的解决方案,只调用一次 geom_line
。
library(ggplot2)
mean_wt <- data.frame(cyl = c(4, 6, 8),
wt = c(2.28, 3.11, 4.00, 3.28, 4.11, 5.00),
wt_col = c("a", "a", "a", "b", "b", "b"))
ggplot() +
geom_point(data = mtcars, aes(mpg, wt)) +
geom_hline(data = mean_wt,aes(yintercept = wt, color = wt_col)) +
facet_wrap(~ cyl, scales = "free", nrow = 1) +
scale_colour_manual(name = "legend",
values = c("a" = "seagreen1",
"b" = "darkorange" ))
我编写了以下示例来说明我的问题。
我想为我绘制的每个 geom_hline 创建我自己的自定义图例和配色方案。我可以通过使用这个答案 Construct a manual legend for a complicated plot.
来实现这一点但是,我正在创建一个函数,它将在绘图上创建任意数量的水平线,并带有一个循环。这意味着我需要动态地将变量提供给 aes_string 函数。然而,
aes_string(yintercept = colname, colour = colname)
不起作用。因为我会得到以下错误'geom_hline Error: Discrete value supplied to continuous scale'
。
这导致我创建了以下解决方案,其中涉及为我希望绘制的每一行创建一个额外的列,其中包含一个可以由 scale_colour_manual 中的向量获取的名称。我觉得这很麻烦而且效率低下。
这按预期工作,但我有 2 个问题:
为什么
aes_string(yintercept = colname, colour = colname_colour)
有效而aes_string(yintercept = colname, colour = colname)
无效。必须有一种更有效的方法来实现我得到的输出,我错过了什么?
示例代码输出:http://imgur.com/a/dvzAM
mean_wt <- data.frame(cyl = c(4, 6, 8)
, wt = c(2.28, 3.11, 4.00)
, wt2 = c(3.28, 4.11, 5.00)
, wt_col = c("a", "a", "a")
, wt_col2 = c("b", "b", "b"))
hline_listA <- list()
for(i in 2:3){
colname <- mean_wt[,i]
colname_colour <- mean_wt[,i+2]
grob <- geom_hline(data =mean_wt
, aes_string(yintercept = colname, colour = colname_colour) )
hline_listA[[i-1]] <- grob
}
ggplot() +
geom_point(data = mtcars, aes(mpg, wt)) +
hline_listA +
facet_wrap(~ cyl, scales = "free", nrow = 1) +
scale_colour_manual(name = "legend", values = c(
"a" = "seagreen1"
, "b" = "darkorange" ))
我无法想象我会在 ggplot 中使用循环做任何事情的情况。实现你想要的通常方法是以 ggplot 可以使用它的方式调整数据框。这是一个更短的解决方案,只调用一次 geom_line
。
library(ggplot2)
mean_wt <- data.frame(cyl = c(4, 6, 8),
wt = c(2.28, 3.11, 4.00, 3.28, 4.11, 5.00),
wt_col = c("a", "a", "a", "b", "b", "b"))
ggplot() +
geom_point(data = mtcars, aes(mpg, wt)) +
geom_hline(data = mean_wt,aes(yintercept = wt, color = wt_col)) +
facet_wrap(~ cyl, scales = "free", nrow = 1) +
scale_colour_manual(name = "legend",
values = c("a" = "seagreen1",
"b" = "darkorange" ))