ggrepel:仅在一个方向排斥文本,并返回被排斥文本的值

时间:2016-02-03 22:07:17

标签: r text ggplot2 label

我有一个数据集,其中每个数据点都有一个受约束的x值(表示定量变量的实际实例),y值是任意的(仅存在以提供展开文本的维度),和一个标签。我的数据集可能非常大,并且通常会出现文本重叠,即使我尝试尽可能多地在y轴上传播数据。

因此,我正在尝试使用新的ggrepel。但是,我试图将文本标签限制在x值位置,同时只允许它们在y方向上相互排斥。

作为一个例子,下面的代码生成了32个数据点的图,其中x值显示了汽车中的汽缸数,y值是随机确定的(没有任何意义,只提供第二个维度)用于文本绘图目的)。在不使用ggrepel的情况下,文本中存在重大的重叠:

library(ggrepel)
library(ggplot2)
set.seed(1)
data = data.frame(x=runif(100, 1, 10),y=runif(100, 1, 10),label=paste0("label",seq(1:100)))
origPlot <- ggplot(data) +
  geom_point(aes(x, y), color = 'red') +
  geom_text(aes(x, y, label = label)) +
  theme_classic(base_size = 16)

Original plot

我可以使用ggrepel修复文本重叠,如下所示。但是,这不仅会改变y值,还会改变x值。我试图避免改变x值,因为它们代表了一个实际的物理意义(气缸数):

repelPlot <- ggplot(data) +
  geom_point(aes(x, y), color = 'red') +
  geom_text_repel(aes(x, y, label = label)) +
  theme_classic(base_size = 16)

enter image description here

作为一个注释,我不能允许文本的x值改变的原因是因为我只绘制文本(而不是点)。然而,似乎ggrepel中的大多数示例保持点的位置(使得它们的值保持为真),并且仅排斥标签的x和y值。然后,点和连接到带有段的标签(你可以在我的第二个绘图示例中看到)。

为了演示目的,我在上面的两个例子中保留了要点。但是,我只保留文本(因此将删除点和段),留下我这样的东西:

repelPlot2 <- ggplot(data) + geom_text_repel(aes(x, y, label = label), segment.size = 0) + theme_classic(base_size = 16)

enter image description here

我的问题有两个:

1)我是否可以仅在y方向排斥文本标签?

2)我是否有可能获得包含文本的新(排斥)y值的结构?

感谢您的任何建议!

2 个答案:

答案 0 :(得分:4)

我认为只能在ggrepel的一个方向排斥文字标签。

我会以不同方式解决这个问题,而是手动生成任意y轴位置。例如,对于示例中的数据集,您可以使用以下代码执行此操作。

我已使用dplyr包按x的值对数据集进行分组,然后创建了一个新的数据列y,其中包含每个组中的行号。然后将行号用作y轴的值。

library(ggplot2)
library(dplyr)

data <- data.frame(x = mtcars$cyl, label = paste0("label", seq(1:32)))

data <- data %>% 
  group_by(x) %>% 
  mutate(y = row_number())

ggplot(data, aes(x = x, y = y, label = label)) + 
  geom_text(size = 2) + 
  xlim(3.5, 8.5) + 
  theme_classic(base_size = 8)

ggsave("filename.png", width = 4, height = 2)

enter image description here

答案 1 :(得分:4)

ggrepel版本0.6.8(使用devtools :: github_install从GitHub安装)现在支持“direction”参数,该参数只能在“x”或“y”方向上排斥标签。

repelPlot2 <- ggplot(data) + geom_text_repel(aes(x, y, label = label), segment.size = 0, direction = "y") + theme_classic(base_size = 16)

获取y值更难 - 一种方法可以是首先使用ggrepel中的“repel_boxes”函数来获取被排斥的值,然后使用geom_text将它们输入到ggplot中。有关该方法的讨论和示例代码,请参阅https://github.com/slowkow/ggrepel/issues/24。请注意,如果使用最新版本,则repel_boxes函数现在也具有“方向”参数,该参数包含“both”,“x”或“y”。