我一开始不包含数据。问题来自于将 geom_smooth 与大量数据点(即大型数据集)一起使用,因此用于说明目的的最小数据示例似乎很难使用(我尝试过)。但如果需要,我可以提交数据。
我有几个变量的分数,并希望了解这些分数在受访者年龄范围内的趋势(横截面数据)。数据现在采用长格式(因此原始变量都在“名称”列下)。
像这样:
age name value
<dbl> <chr> <dbl>
1 40 mo_clean 1
2 40 mo_groc 3
3 40 mo_trans 1
4 40 mo_digi 3
5 40 mo_emo 3
6 40 mo_activ 1
7 40 mo_supv 1
8 40 mo_doct 1
9 39 mo_clean 1
10 39 mo_groc 1
# … with 42,030 more rows
我想要:
- 使用
geom_smooth
和geom_label
和 - 然后切换到
ggrepel::geom_label_repel
以避免标签重叠
让标签与geom_smooth
一起工作变得很困难,但我设法用下面的代码做到了这一点:
library(ggplot2)
library(ggrepel)
df %>%
{
ggplot(df, aes(age, value, label = name, color = name)) +
geom_smooth(se = FALSE) +
guides(color = "none") +
geom_label(
data = group_by(., name) %>%
do(augment(loess(value ~ age, .))) %>%
filter(age == max(age)),
aes(age, .fitted), nudge_x = 2
)
} +
scale_x_continuous(breaks = seq(35, 65, by = 5)) +
xlab("Age") +
ylab(" ") +
theme(text = element_text(size = 14))
给出了这个结果:
现在,正如预期的那样,由于数据点较多,用 geom_rabel_repel
替换 geom_label
不起作用。我收到以下错误消息:
`geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
Warning message:
ggrepel: 720 unlabeled data points (too many overlaps). Consider increasing max.overlaps
并且图中的所有标签都被删除。
我认为增加 max.overlaps
并不是正确的方法。只是为了说明极端情况,使用 max.overlaps = Inf
:
[...]
geom_label_repel(
data = group_by(., name) %>%
do(augment(loess(value ~ age, .))) %>%
filter(age == max(age)),
aes(age, .fitted),
max.overlaps = Inf
)
[...]
有什么提示吗?例如在哪里可以找到帮助(甚至代码建议)?很多网络搜索都没有给我我正在寻找的东西:如何将geom_smooth
与geom_label_repel
结合起来以获得一个漂亮的图,其中每条平滑线都被标记,并且标签不重叠。
——
我的问题涉及具有大量数据点的 geom_smooth
,链接的问题 ( Plot labels at ends of lines ) 涉及具有少量数据点的 geom_line
。
但请注意,其他帖子的一些答案提到了 geom_smooth
并使用 geom_smooth
提供了代码。因此,我建议查看这些答案,尽管它们没有解决我的问题。
最佳答案
确实,@TarJae 是对的:添加 unique
是正确的方法。
[...]
{
ggplot(df, aes(age, value, label = name, color = name)) +
geom_smooth(se = FALSE) +
guides(color = "none") +
geom_label_repel(
data = group_by(., name) %>%
do(augment(loess(value ~ age, .))) %>%
filter(age == max(age)),
aes(age, .fitted),
# "unique" added (and max.overlaps part dropped)
stat = "unique",
# Some *minor* prettifying
direction = "y",
nudge_x = 0.7
)
} +
[...]
当前结果,无需进一步操作/美化:
因此,在这种情况下,错误消息会导致错误的道路。
关于 tjebo 在替代答案中的建议:我相信添加 stat=unique
是比 tjebo 答案中的第二 block 更好的解决方案(尽管结果数字仍然不是我想要的)。
library(tidyverse)
library(ggrepel)
df <-
diamonds %>% select(age = table, name = color, value = price)
df %>%
{
ggplot(df, aes(age, value, label = name, color = name)) +
geom_smooth(se = FALSE) +
geom_label_repel(
data = group_by(., name) %>%
do(broom::augment(loess(value ~ age, .))) %>%
filter(age == max(age)),
aes(age, .fitted),
stat = "unique"
)
}
#> `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
关于r - geom_smooth 和 geom_label_repel 创建不需要的多个标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72930035/