Как я могу добавить легенду, которая считает точки выше или ниже определенного значения в ggplot2? Участок вулкана - PullRequest
2 голосов
/ 05 мая 2020

Я пытаюсь создать график вулкана (точечный график), где точки выше определенного значения y окрашены в градиент от красного к зеленому в зависимости от их значения x, и добавляю легенду, которая указывает количество точек, которые выше этих значений.

У меня есть код, похожий на этот:

set.seed(123)
x <- runif(600, -3, 3)
y <- runif(600, 0, 0.6)
df<- as.data.frame(cbind(x,y))

df %>% ggplot(aes(x, -log10(y), color=x)) +
  geom_point()+
  geom_hline(yintercept=1.3, color="darkgrey")+
  scale_fill_gradient(low="red",high="green", aesthetics = "color") 

Который (с моими данными) дает этот график:

enter image description here

Но я хочу, чтобы легенда подсчитывала количество точек, которые y> 1,3 и x> 0 и y> 1,3 и x <0 отдельно (чтобы не отображать цветовую полосу), и я хочу, чтобы точки под линией быть черным. </p>

Кто-нибудь может мне помочь?

Спасибо !!!!

1 Ответ

2 голосов
/ 05 мая 2020

Одно замечание: легенды в ggplot настраиваются только для объяснения того, как представлена ​​эстетика. Чтобы легенды отображали результаты или данные (например, количество вашей информации), вы должны использовать подход, отличный от того, что встроено в ggplot2.

С учетом сказанного, вот пример с использованием подмножества набора данных бриллиантов.

Настройка данных

Примечание. Я использую образец набора данных бриллиантов, потому что я ленив и не хотел ждать 50000+ точек данные для рендеринга. : /

set.seed(12345)
di <- diamonds[sample(1:nrow(diamonds), 5000),]

Я собираюсь настроить график так, чтобы отображать глубину по оси x и цену по оси y. Мы суммируем количество наблюдений с большой глубиной (> средняя глубина) и низкой глубиной (<средняя глубина), и все они имеют цену> 6000. Мы будем использовать эту таблицу позже.

di.summary <- as.data.frame(
    di %>% dplyr::filter(price > 6000) %>%
    group_by(depth > mean(di$depth)) %>% tally()
)
chartTable <- cbind(c('Low\nDepth', 'High\nDepth'), di.summary[,2])

Basi c График: настройка цвета Geom_point

Это иллюстрирует метод, который можно использовать для вашей диаграммы, чтобы изменить цвет только определенных точек. В этом случае я хочу, чтобы были окрашены только точки с ценой выше 6000, а все остальные точки были представлены серыми точками. Самый простой способ сделать это - сделать два вызова geom_point и использовать разные наборы данных. К одному будет применен цвет aestheti c (в пределах aes()), а для другого будет указан серый цвет вне функции aes().

p <- ggplot(di, aes(depth, price)) +
    geom_point(data=di[which(di$price > 6000),], aes(color=depth), size=1) +
    geom_point(data=di[which(di$price <= 6000),], color='gray80', size=1) +
    geom_hline(yintercept=6000) +
    geom_vline(xintercept=mean(di$depth), linetype=2) +
    scale_color_gradient(high='red', low='green')
p

enter image description here

Добавление таблицы результатов

Чтобы отобразить таблицу на вашем графике, нам нужно будет использовать «grob» (сокращение от «Graphics Object» , Я считаю). Я собираюсь преобразовать таблицу, используя tableGrob из библиотеки gridExtra. Затем вы передаете этот объект grob в annotation_custom() и указываете местоположение на вашей диаграмме.

Еще один момент: мы планируем разместить таблицу в правом нижнем углу вне площадь участка (под легендой). Для этого нам нужно освободить место для стола, добавив справа поле графика. Нам также необходимо отключить обрезку, чтобы аннотация могла быть представлена ​​за пределами области графика.

library(gridExtra)

p +
  coord_cartesian(clip='off') +
  theme(
    plot.margin = margin(0,40,0,0)
  ) +
  annotation_custom(
    grob=tableGrob(chartTable, theme=ttheme_default(base_size = 9)),
    xmin=74.5, xmax=76, ymin=0, ymax=5000
  )

enter image description here

Вы можете использовать аналогичный подход для ваши данные.

Альтернативный подход с использованием текстовых аннотаций

Альтернативный подход к использованию tableGrob мог бы заключаться в простом представлении количества точек с помощью текстовых аннотаций. Я покажу здесь пример:

p +
    annotate(
        geom='label',
        x=min(di$depth), y=0.8*max(di$price),
        hjust=0,
        label=paste0('n=',di.summary[1,2])
    ) +
    annotate(
        geom='label',
        x=max(di$depth), y=0.8*max(di$price),
        hjust=1,
        label=paste0('n=',di.summary[2,2])
    )

enter image description here

Хотя это не ваши данные, приведенный выше пример должен дать вам достаточно информации, чтобы понять как это можно применить к вашим собственным данным.

...