r - R ggplot2 ggrepel - 在知道所有点的同时标记点的子集
问题描述
我有一个相当密集的散点图,我正在使用 R 'ggplot2' 构建,我想使用 'ggrepel' 标记点的子集。我的问题是我想在散点图中绘制所有点,但只用 ggrepel 标记一个子集,当我这样做时,ggrepel 在计算放置标签的位置时不会考虑图中的其他点,这会导致到与图上其他点重叠的标签(我不想标记)。
这是说明该问题的示例图。
# generate data:
library(data.table)
library(stringi)
set.seed(20180918)
dt = data.table(
name = stri_rand_strings(3000,length=6),
one = rnorm(n = 3000,mean = 0,sd = 1),
two = rnorm(n = 3000,mean = 0,sd = 1))
dt[, diff := one -two]
dt[, diff_cat := ifelse(one > 0 & two>0 & abs(diff)>1, "type_1",
ifelse(one<0 & two < 0 & abs(diff)>1, "type_2",
ifelse(two>0 & one<0 & abs(diff)>1, "type_3",
ifelse(two<0 & one>0 & abs(diff)>1, "type_4", "other"))))]
# make plot
ggplot(dt, aes(x=one,y=two,color=diff_cat))+
geom_point()
如果我只绘制我想要标记的点的子集,那么 ggrepel 能够以相对于其他点和标签的非重叠方式放置所有标签。
ggplot(dt[abs(diff)>2 & (!diff_cat %in% c("type_3","type_4","other"))],
aes(x=one,y=two,color=diff_cat))+
geom_point()+
geom_text_repel(data = dt[abs(diff)>2 & (!diff_cat %in% c("type_3","type_4","other"))],
aes(x=one,y=two,label=name))
但是,当我想同时绘制这个数据子集和原始数据时,我会得到带有标签的重叠点:
# now add labels to a subset of points on the plot
ggplot(dt, aes(x=one,y=two,color=diff_cat))+
geom_point()+
geom_text_repel(data = dt[abs(diff)>2 & (!diff_cat %in% c("type_3","type_4","other"))],
aes(x=one,y=two,label=name))
如何让点子集的标签不与原始数据中的点重叠?
解决方案
您可以尝试以下方法:
- 为原始数据中的所有其他点分配一个空白标签 (
""
),以便geom_text_repel
在相互排斥标签时将它们考虑在内; - 将
box.padding
参数从默认值0.25
增加到更大的值,以获得更大的标签之间的距离; - 增加 x 和 y 轴限制,以在四个侧面为标签提供更多空间来排斥。
示例代码(带box.padding = 1
):
ggplot(dt,
aes(x = one, y = two, color = diff_cat)) +
geom_point() +
geom_text_repel(data = . %>%
mutate(label = ifelse(diff_cat %in% c("type_1", "type_2") & abs(diff) > 2,
name, "")),
aes(label = label),
box.padding = 1,
show.legend = FALSE) + #this removes the 'a' from the legend
coord_cartesian(xlim = c(-5, 5), ylim = c(-5, 5)) +
theme_bw()
这是另一个尝试,使用box.padding = 2
:
(注意:我使用的是 ggrepel 0.8.0。我不确定早期软件包版本是否具备所有功能。)
推荐阅读
- javascript - 手动编写 .htaccess 时,React 不会路由
- java - Java Mockito - 我如何测试这个方法?
- php - `publish_post` 上的 WordPress 函数运行两次(将值增加 2 而不是 1)
- c++ - SDL2 不创建三角形
- python - 在 python 中,我无法获得正确的产品
- scala - Scala 的 Nothing vs 部分统一
- css - 为每个自定义角色加载 CSS
- python - 我的弹丸在空中改变方向 Pygame 需要帮助
- node.js - Mongoose 在更新模型时不会插入数组
- optimization - 从一群人中建立一个团队,同时最大化团队中的总人数并遵守团队内总技能的限制