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))

сюжет с ярлыками

Как сделать так, чтобы метки для подмножества точек не перекрывали точки из исходных данных?


person Reilstein    schedule 19.09.2018    source источник


Ответы (1)


Вы можете попробовать следующее:

  1. Назначьте пустую метку ("") всем остальным точкам из исходных данных, чтобы geom_text_repel принимала их во внимание при отталкивании меток друг от друга;
  2. Увеличьте параметр box.padding со значения по умолчанию 0.25 до некоторого большего значения, чтобы увеличить расстояние между метками;
  3. Увеличьте пределы по осям 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:

сюжет 2

(Примечание: я использую ggrepel 0.8.0. Я не уверен, что все функции доступны для более ранних версий пакета.)

person Z.Lin    schedule 19.09.2018
comment
Замечательное решение! - person Calum You; 19.09.2018
comment
действительно хорошо, я не знала обо всем этом, спасибо, что поделились - person denis; 19.09.2018
comment
Отличное решение! Вы даже ответили на некоторые вопросы, которые я не думал задавать :). - person Reilstein; 19.09.2018