我想用具有相同标签的几个点来注释散点图。我想给它们全部贴上标签(而不仅仅是其中的一部分),但是有这么多冗余标签,这真是一团糟。 有没有一种方法可以使用 ggrepel::geom_text_repel 让一个标签指向具有相同标签的所有点?
我附上最简单的情况:
df <- data.frame(
group = c("A", "A", "B", "B"),
x = c(1, 2, 3, 4),
y = c(2, 3, 4, 5)
)
ggplot(df, aes(x, y)) +
geom_point() +
geom_text_repel(data=df, aes(label=group), box.padding = 0.5, force = 4)
PS:@user2862862在2019年发布了同样的问题,但在一个标签用于多个点
中没有正确的答案这是实现您想要的目标的方法。然而,正如 @AllanCameron 在评论中提到的,这种方法的适当性“严重”依赖于数据。我提供了额外的示例来说明潜在的问题。 此方法涉及计算每组的平均 xy,然后再创建两个数据帧:一个用于线条 (df1),一个用于标签 (df2):
library(dplyr)
library(tidyr)
library(ggplot2)
# Your example data (Example1): IMPORTANT: note modified x and y column names,
# you will first need to change your x and y columns to x_1 and y_1
df <- data.frame(
group = c("A", "A", "B", "B"),
x_1 = c(1, 2, 3, 4),
y_1 = c(2, 3, 4, 5)
)
# Create df for plotting lines from original points to group's mean point
df1 <- df %>%
group_by(group) %>%
mutate(x_2 = mean(x_1),
y_2 = mean(y_1)) %>%
pivot_longer(-c(group),
names_to = c(".value", "var"),
names_sep = "_")
# Create df for single group label
df2 <- df %>%
group_by(group) %>%
mutate(x_2 = mean(x_1),
y_2 = mean(y_1)) %>%
select(-ends_with("1")) %>%
distinct()
# Plot
ggplot() +
geom_path(data = df1,
aes(x, y, group = group),
colour = "grey") +
geom_point(data = df,
aes(x_1, y_1),
size = 2) +
geom_text(data = df2,
aes(x_2, y_2, label = group),
size = 5)
现在考虑这两个其他示例数据框:
# Example2
df <- data.frame(
group = rep(c("A", "B"), each = 3),
x_1 = c(1, 1.5, 2, 3, 3.5, 4),
y_1 = c(2, 4, 3, 4, 2.5, 5)
)
# Example3
set.seed(1)
df <- data.frame(group = rep(c("A", "B", "C"), each = 10),
x_1 = runif(n = 30, min = 1, max = 4),
y_1 = runif(n = 30, min = 2, max = 5))
Example1 和Example2 看起来不错,但是您提出的方法对于Example3 这样的数据来说不能很好地扩展。每个组的线交叉,这使得解释变得困难。如果您的完整数据更复杂并且包含大量点(例如示例 3),则使用颜色(或形状)可以更有效地传达数据中发生的情况:
ggplot() +
geom_point(data = df,
aes(x_1, y_1, colour = group),
size = 2) +
labs(x = "x", y = "y")