如何避免图例中 geom_vline() 和 geom_hline 在同一个散点图上的交叉效应?
How to avoid the crossing effect in legend with geom_vline() and geom_hline on the same scatter plot?
我用 geom_hline()
和 geom_vline()
创建了一个散点图,该图很好,但图例条目不是我想要的显示方式。 vline
(恢复)和hline
(阈值)在图例中相互交叉,令人困惑。我希望恢复图例条目为橙色垂直线,阈值图例条目为水平黑线。
我尝试了其他帖子中建议的几项操作,使用 guide_legend(override.aes())
或 show.legend = F
但要么它更改了上面“类型”部分的图例条目(它删除了行并保留了彩色圆圈)或者它只是删除了其中一行的图例条目。
这是我当前的代码:
ggplot(data = tst_formule[tst_formule$River != "Roya",], aes(x=Year, y = BRI_adi_moy_transect, shape = River, col = Type)) +
geom_point(size = 3) +
geom_errorbar(aes(ymin = BRI_adi_moy_transect - SD_transect, ymax = BRI_adi_moy_transect + SD_transect), width = 0.4) +
scale_shape_manual(values = c(15, 16, 17)) +
scale_colour_manual(values = c("chocolate1", "darkcyan")) +
geom_vline(aes(xintercept = Restauration_year, linetype = "Restoration"), colour = "chocolate1") +
geom_hline(aes(yintercept = 0.004, linetype = "Threshold"), colour= 'black') +
scale_linetype_manual(name = NULL, values = c(4, 5)) +
scale_y_continuous("BRI*", limits = c(min(tst_formule$BRI_adi_moy_transect - tst_formule$SD_transect),
max(tst_formule$BRI_adi_moy_transect + tst_formule$SD_transect))) +
scale_x_continuous(limits = c(min(tst_formule$Year - 1),max(tst_formule$Year + 1)), breaks = scales::breaks_pretty(n = 6)) +
theme_bw() +
facet_wrap(vars(River))
这是我的 dput
数据:
structure(list(River = c("Durance", "Durance", "Durance", "Durance",
"Roya", "Var"), Reach = c("La Brillanne", "Les Mées", "La Brillanne",
"Les Mées", "Basse vallée", "Basse vallée"), Type = c("restaured",
"target", "restaured", "target", "witness", "restaured"), Year = c(2017,
2017, 2012, 2012, 2018, 2011), Restauration_year = c(2013, 2013,
2013, 2013, 2000, 2009), BRI_adi_moy_transect = c(0.0028, 0.0017,
0.0033, 0.0018, 0.009, 0.0045), SD_transect = c(0.00128472161839638,
0.000477209421076879, 0.00204050725984513, 0.000472466654940182,
0.00780731734792112, 0.00310039904793707)), row.names = c(NA,
6L), class = "data.frame")
知道如何让它做我想做的事吗?
这是本期中记录的一个已知问题 https://github.com/tidyverse/ggplot2/issues/2483
那里没有提供答案,除了自定义绘制的图例键,我认为这是不可能的
我发现了一个令人难以置信的不可推广的解决方法,但我想我还是会分享。解决方法是编写键字形函数,根据线型有条件地输出键。这有点硬编码,所以我不知道如何概括这一点。这是两个函数:
glyph_vline <- function(data, params, size) {
if (data$linetype == 4) {
draw_key_vline(data, params, size)
} else {
zeroGrob()
}
}
glyph_hline <- function(data, params, size) {
if (data$linetype == 5) {
draw_key_path(data, params, size)
} else {
zeroGrob()
}
}
您需要将这些输入到 vline/hline 层的 key_glyph
参数中。像这样:
ggplot(data = tst_formule[tst_formule$River != "Roya",], aes(x=Year, y = BRI_adi_moy_transect, shape = River, col = Type)) +
geom_point(size = 3) +
geom_errorbar(aes(ymin = BRI_adi_moy_transect - SD_transect, ymax = BRI_adi_moy_transect + SD_transect), width = 0.4) +
scale_shape_manual(values = c(15, 16, 17)) +
scale_colour_manual(values = c("chocolate1", "darkcyan")) +
geom_vline(aes(xintercept = Restauration_year, linetype = "Restoration"),
colour = "chocolate1", key_glyph = glyph_vline) +
geom_hline(aes(yintercept = 0.004, linetype = "Threshold"),
colour= 'black', key_glyph = glyph_hline) +
scale_linetype_manual(name = NULL, values = c(4, 5)) +
scale_y_continuous("BRI*", limits = c(min(tst_formule$BRI_adi_moy_transect - tst_formule$SD_transect),
max(tst_formule$BRI_adi_moy_transect + tst_formule$SD_transect))) +
scale_x_continuous(limits = c(min(tst_formule$Year - 1),max(tst_formule$Year + 1)), breaks = scales::breaks_pretty(n = 6)) +
theme_bw() +
facet_wrap(vars(River))
创建两个线型比例。我已将 vline/hline 调用放在底部以获得更好的可见性。
library(tidyverse)
library(ggnewscale)
ggplot(data = tst_formule[tst_formule$River != "Roya",], aes(x=Year, y = BRI_adi_moy_transect, shape = River, col = Type)) +
geom_point(size = 3) +
geom_errorbar(aes(ymin = BRI_adi_moy_transect - SD_transect, ymax = BRI_adi_moy_transect + SD_transect), width = 0.4) +
scale_shape_manual(values = c(15, 16, 17)) +
scale_colour_manual(values = c("chocolate1", "darkcyan")) +
scale_y_continuous("BRI*", limits = c(min(tst_formule$BRI_adi_moy_transect - tst_formule$SD_transect),
max(tst_formule$BRI_adi_moy_transect + tst_formule$SD_transect))) +
scale_x_continuous(limits = c(min(tst_formule$Year - 1),max(tst_formule$Year + 1)), breaks = scales::breaks_pretty(n = 6)) +
theme_bw() +
facet_wrap(vars(River)) +
# here starts the trick
geom_vline(aes(xintercept = Restauration_year, linetype = "Restauration"), colour = "chocolate1") +
scale_linetype_manual(name = NULL, values = 4) +
# ggnewscale is an amazing package
new_scale("linetype") +
# now do the same for geom_hline
geom_hline(aes(yintercept = 0.004, linetype = "Threshold"), colour= 'black') +
scale_linetype_manual(name = NULL, values = 5)
我用 geom_hline()
和 geom_vline()
创建了一个散点图,该图很好,但图例条目不是我想要的显示方式。 vline
(恢复)和hline
(阈值)在图例中相互交叉,令人困惑。我希望恢复图例条目为橙色垂直线,阈值图例条目为水平黑线。
我尝试了其他帖子中建议的几项操作,使用 guide_legend(override.aes())
或 show.legend = F
但要么它更改了上面“类型”部分的图例条目(它删除了行并保留了彩色圆圈)或者它只是删除了其中一行的图例条目。
这是我当前的代码:
ggplot(data = tst_formule[tst_formule$River != "Roya",], aes(x=Year, y = BRI_adi_moy_transect, shape = River, col = Type)) +
geom_point(size = 3) +
geom_errorbar(aes(ymin = BRI_adi_moy_transect - SD_transect, ymax = BRI_adi_moy_transect + SD_transect), width = 0.4) +
scale_shape_manual(values = c(15, 16, 17)) +
scale_colour_manual(values = c("chocolate1", "darkcyan")) +
geom_vline(aes(xintercept = Restauration_year, linetype = "Restoration"), colour = "chocolate1") +
geom_hline(aes(yintercept = 0.004, linetype = "Threshold"), colour= 'black') +
scale_linetype_manual(name = NULL, values = c(4, 5)) +
scale_y_continuous("BRI*", limits = c(min(tst_formule$BRI_adi_moy_transect - tst_formule$SD_transect),
max(tst_formule$BRI_adi_moy_transect + tst_formule$SD_transect))) +
scale_x_continuous(limits = c(min(tst_formule$Year - 1),max(tst_formule$Year + 1)), breaks = scales::breaks_pretty(n = 6)) +
theme_bw() +
facet_wrap(vars(River))
这是我的 dput
数据:
structure(list(River = c("Durance", "Durance", "Durance", "Durance",
"Roya", "Var"), Reach = c("La Brillanne", "Les Mées", "La Brillanne",
"Les Mées", "Basse vallée", "Basse vallée"), Type = c("restaured",
"target", "restaured", "target", "witness", "restaured"), Year = c(2017,
2017, 2012, 2012, 2018, 2011), Restauration_year = c(2013, 2013,
2013, 2013, 2000, 2009), BRI_adi_moy_transect = c(0.0028, 0.0017,
0.0033, 0.0018, 0.009, 0.0045), SD_transect = c(0.00128472161839638,
0.000477209421076879, 0.00204050725984513, 0.000472466654940182,
0.00780731734792112, 0.00310039904793707)), row.names = c(NA,
6L), class = "data.frame")
知道如何让它做我想做的事吗?
这是本期中记录的一个已知问题 https://github.com/tidyverse/ggplot2/issues/2483
那里没有提供答案,除了自定义绘制的图例键,我认为这是不可能的
我发现了一个令人难以置信的不可推广的解决方法,但我想我还是会分享。解决方法是编写键字形函数,根据线型有条件地输出键。这有点硬编码,所以我不知道如何概括这一点。这是两个函数:
glyph_vline <- function(data, params, size) {
if (data$linetype == 4) {
draw_key_vline(data, params, size)
} else {
zeroGrob()
}
}
glyph_hline <- function(data, params, size) {
if (data$linetype == 5) {
draw_key_path(data, params, size)
} else {
zeroGrob()
}
}
您需要将这些输入到 vline/hline 层的 key_glyph
参数中。像这样:
ggplot(data = tst_formule[tst_formule$River != "Roya",], aes(x=Year, y = BRI_adi_moy_transect, shape = River, col = Type)) +
geom_point(size = 3) +
geom_errorbar(aes(ymin = BRI_adi_moy_transect - SD_transect, ymax = BRI_adi_moy_transect + SD_transect), width = 0.4) +
scale_shape_manual(values = c(15, 16, 17)) +
scale_colour_manual(values = c("chocolate1", "darkcyan")) +
geom_vline(aes(xintercept = Restauration_year, linetype = "Restoration"),
colour = "chocolate1", key_glyph = glyph_vline) +
geom_hline(aes(yintercept = 0.004, linetype = "Threshold"),
colour= 'black', key_glyph = glyph_hline) +
scale_linetype_manual(name = NULL, values = c(4, 5)) +
scale_y_continuous("BRI*", limits = c(min(tst_formule$BRI_adi_moy_transect - tst_formule$SD_transect),
max(tst_formule$BRI_adi_moy_transect + tst_formule$SD_transect))) +
scale_x_continuous(limits = c(min(tst_formule$Year - 1),max(tst_formule$Year + 1)), breaks = scales::breaks_pretty(n = 6)) +
theme_bw() +
facet_wrap(vars(River))
创建两个线型比例。我已将 vline/hline 调用放在底部以获得更好的可见性。
library(tidyverse)
library(ggnewscale)
ggplot(data = tst_formule[tst_formule$River != "Roya",], aes(x=Year, y = BRI_adi_moy_transect, shape = River, col = Type)) +
geom_point(size = 3) +
geom_errorbar(aes(ymin = BRI_adi_moy_transect - SD_transect, ymax = BRI_adi_moy_transect + SD_transect), width = 0.4) +
scale_shape_manual(values = c(15, 16, 17)) +
scale_colour_manual(values = c("chocolate1", "darkcyan")) +
scale_y_continuous("BRI*", limits = c(min(tst_formule$BRI_adi_moy_transect - tst_formule$SD_transect),
max(tst_formule$BRI_adi_moy_transect + tst_formule$SD_transect))) +
scale_x_continuous(limits = c(min(tst_formule$Year - 1),max(tst_formule$Year + 1)), breaks = scales::breaks_pretty(n = 6)) +
theme_bw() +
facet_wrap(vars(River)) +
# here starts the trick
geom_vline(aes(xintercept = Restauration_year, linetype = "Restauration"), colour = "chocolate1") +
scale_linetype_manual(name = NULL, values = 4) +
# ggnewscale is an amazing package
new_scale("linetype") +
# now do the same for geom_hline
geom_hline(aes(yintercept = 0.004, linetype = "Threshold"), colour= 'black') +
scale_linetype_manual(name = NULL, values = 5)