#r #ggplot2 #dplyr #tidyverse
Вопрос:
Я хотел бы пометить свой geom_smooth
в r, но метки расположены ближе к фактическим точкам, а не к линиям.
Данные:
df lt;- structure(list(t = c(45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65), x = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), name = c("P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4", "P1", "P2", "P2 ", "P3", "P4"), value = c(48L, 132L, 111L, 115L, 2L, 58L, 126L, 82L, 74L, 0L, 45L, 119L, 78L, 87L, 0L, 56L, 106L, 105L, 88L, 1L, 52L, 78L, 91L, 107L, 1L, 35L, 96L, 86L, 98L, 1L, 61L, 118L, 90L, 108L, 2L, 45L, 114L, 93L, 98L, 2L, 55L, 108L, 78L, 76L, 7L, 44L, 97L, 94L, 96L, 0L, 40L, 111L, 93L, 88L, 1L, 43L, 78L, 66L, 113L, 2L, 20L, 57L, 84L, 41L, 0L, 17L, 51L, 81L, 34L, 0L, 40L, 55L, 64L, 32L, 0L, 25L, 67L, 71L, 37L, 0L, 16L, 67L, 60L, 57L, 0L, 23L, 46L, 62L, 47L, 1L, 34L, 75L, 68L, 39L, 0L, 34L, 60L, 85L, 24L, 0L, 20L, 58L, 63L, 37L, 1L)), row.names = c(NA, -105L), class = c("tbl_df", "tbl", "data.frame"))
Мой код:
df %gt;% group_by(name) %gt;% # New column to label the first and last values mutate(label = case_when( t == min(t) | t == max(t) ~ name, TRUE ~ NA_character_)) %gt;% ggplot(aes(x = t, y = value, color = name, group = interaction(x, name), shape = name)) geom_smooth(se = F) geom_vline(xintercept = 57, linetype = "dashed", lwd = 0.3) scale_color_discrete(guide = 'none') geom_label_repel(aes(label = label))
Кроме того, можно ли избавиться от линий, указывающих на сглаженные лессовые кривые?
Комментарии:
1. вы пробовали просто использовать
ggplot2::geom_label
?2. Небольшие линии, указывающие на сглаженные лессовые кривые, сделаны ggrepel. Чтобы удалить их, либо используйте
geom_label
, как предложено выше, либоgeom_label_repel(..., min.segment.length = 1)
в этом случае они печатаются только тогда, когда этикетка находится слишком далеко от кривой из-за отталкивания. Другой вариант-это..., segment.colour=NA, ...
Ответ №1:
Одним из вариантов достижения желаемого результата было бы использование stat="smooth"
в ggrepel::geom_label_repel
. Это приведет к размещению меток на установленных точках, а не на точках данных. Однако, чтобы это сработало, вам нужно добавить метки на лету внутри geom_label_repel
, например, с помощью after_stat(ifelse(x %in% range(x), color, NA_character_))
:
library(ggplot2) library(ggrepel) ggplot(df, aes(x = t, y = value, color = name, group = interaction(x, name), shape = name)) geom_smooth(se = F) geom_vline(xintercept = 57, linetype = "dashed", lwd = 0.3) scale_color_discrete(guide = "none") ggrepel::geom_label_repel(aes(label = after_stat(ifelse(x %in% range(x), color, NA_character_))), stat = "smooth")
РЕДАКТИРОВАТЬ Вероятно, существуют разные маршруты для размещения меток слева (справа) в (нижнем) верхнем конце диапазона данных. Мой подход, вероятно, не элегантен. Но после того, как в последнее время мне пришлось подготовить множество диаграмм с надписями на конечных точках, я решил, что сделать это с помощью двух текстовых слоев, на мой взгляд, самый простой способ добиться этого, поскольку он позволяет нам нажимать, чтобы сдвинуть надписи влево или вправо. Чтобы сделать эту работу, я увеличил масштаб x, чтобы освободить место для надписей. Кроме того, я удалил сегменты в правке и установил .direction = "y"
так что метки отталкиваются только в направлении y.
library(ggplot2) library(ggrepel) ggplot(df, aes(x = t, y = value, color = name, group = interaction(x, name), shape = name)) geom_smooth(se = F) geom_vline(xintercept = 57, linetype = "dashed", lwd = 0.3) scale_color_discrete(guide = "none") scale_x_continuous(expand = c(.1, .1)) ggrepel::geom_label_repel(aes(label = after_stat(ifelse(x %in% range(x)[1], color, NA_character_))), stat = "smooth", nudge_x = -1, min.segment.length = Inf, direction = "y") ggrepel::geom_label_repel(aes(label = after_stat(ifelse(x %in% range(x)[2], color, NA_character_))), stat = "smooth", nudge_x = 1, min.segment.length = Inf, direction = "y")
Комментарии:
1. Спасибо за этот замечательный ответ. Еще одна вещь, вы знаете, как я могу разместить метки за пределами xranges? например, те, что справа, должны быть при x = 65 и далее, а те, что слева, должны быть меньше x = 45?