ggplot:避免将 geom_text() 放置在彼此之上

问题描述 投票:0回答:1

我有以下常见场景:我有某个点的气候数据观测和预测。为了评估模型性能,将数据绘制成线图,并且指标应以相应线条的颜色显示为文本。
生成的图基本上包含我需要的所有元素,但 geom_text() 显示的标签彼此不可读。在左侧,两个预测的值相同,因此只有一个文本可见,但它们也相互重叠。我遇到的问题可以在右侧的两个图中清楚地看到。

resulting plot

我该如何调整?到目前为止,我尝试使用 geom_text_repel() (导致丢失标签)并在循环中使用 geom_text() ,其中 geom_text() 的 y 和 x 不同。 任何帮助表示赞赏!

数据在这里:

准备绘图的数据:

structure(list(time = structure(c(1506826800, 1506826800, 1509505200,  1509505200, 1512097200, 1512097200, 1514775600, 1514775600, 1517454000,  1517454000, 1519873200, 1519873200, 1522551600, 1522551600, 1525143600,  1525143600, 1527822000, 1527822000, 1530414000, 1530414000, 1533092400,  1533092400, 1506826800, 1506826800, 1509505200, 1509505200, 1512097200,  1512097200, 1514775600, 1514775600, 1517454000, 1517454000, 1519873200,  1519873200, 1522551600, 1522551600, 1525143600, 1525143600, 1527822000,  1527822000, 1530414000, 1530414000, 1533092400, 1533092400, 1506826800,  1506826800, 1509505200, 1509505200, 1512097200, 1512097200, 1514775600,  1514775600, 1517454000, 1517454000, 1519873200, 1519873200, 1522551600,  1522551600, 1525143600, 1525143600, 1527822000, 1527822000, 1530414000,  1530414000, 1533092400, 1533092400, 1506826800, 1506826800, 1509505200,  1509505200, 1512097200, 1512097200, 1514775600, 1514775600, 1517454000,  1517454000, 1519873200, 1519873200, 1522551600, 1522551600, 1525143600,  1525143600, 1527822000, 1527822000, 1530414000, 1530414000, 1533092400,  1533092400, 1506826800, 1506826800, 1509505200, 1509505200, 1512097200,  1512097200, 1514775600, 1514775600, 1517454000, 1517454000, 1519873200,  1519873200, 1522551600, 1522551600, 1525143600, 1525143600, 1527822000,  1527822000, 1530414000, 1530414000, 1533092400, 1533092400, 1506826800,  1506826800, 1509505200, 1509505200, 1512097200, 1512097200, 1514775600,  1514775600, 1517454000, 1517454000, 1519873200, 1519873200, 1522551600,  1522551600, 1525143600, 1525143600, 1527822000, 1527822000, 1530414000,  1530414000, 1533092400, 1533092400), tzone = "", class = c("POSIXct",  "POSIXt")), Source = c("Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "Pred1 (wmo correction)", "Pred1 (wmo correction)", "Pred1 (wmo correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)",  "Observation", "Observation", "Observation", "Observation", "Observation",  "Observation", "Observation", "Observation", "Observation", "Observation",  "Observation", "Observation", "Observation", "Observation", "Observation",  "Observation", "Observation", "Observation", "Observation", "Observation",  "Observation", "Observation", "Observation", "Observation", "Observation",  "Observation", "Observation", "Observation", "Observation", "Observation",  "Observation", "Observation", "Observation", "Observation", "Observation",  "Observation", "Observation", "Observation", "Observation", "Observation",  "Observation", "Observation", "Observation", "Observation"),  Station = c("PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3",  "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3",  "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG4", "PG4", "PG4",  "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4",  "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4",  "PG4", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3",  "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3",  "PG3", "PG3", "PG3", "PG3", "PG3", "PG4", "PG4", "PG4", "PG4",  "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4",  "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4",  "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3",  "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3", "PG3",  "PG3", "PG3", "PG3", "PG3", "PG4", "PG4", "PG4", "PG4", "PG4",  "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4",  "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4", "PG4"),  variable = c("temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip", "temp", "precip", "temp", "precip", "temp", "precip",  "temp", "precip", "temp", "precip", "temp", "precip", "temp",  "precip"), value = c(288.84334108871, 43.0802236032481, 283.292141125,  50.5762518752008, 278.912795685484, 63.3694839260056, 280.065486854839,  46.944432518432, 276.980215044643, 47.0325918649175, 278.967870120968,  412.167444639785, 282.627421083333, 78.7950463642617, 284.651787217742,  43.4694896443769, 290.522796125, 0.7037754037678, 295.152023306452,  0, 295.091175080645, 4.430099105969, 285.346147016129, 55.577232932,  279.793625208333, 105.825640333, 275.887160080645, 166.87525632,  276.4884575, 81.029784211, 273.029221741071, 107.1414037242,  274.487727258065, 846.184536217, 278.949141125, 276.734242477,  280.430190080645, 35.5217026375, 286.738608583333, 4.42854513,  291.796912903226, 0, 290.786353104839, 26.342758098, 288.84334108871,  44.388101819812, 283.292141125, 52.6243076692389, 278.912795685484,  67.5961305373254, 280.065486854839, 36.5236296409472, 276.980215044643,  44.4754013996746, 278.967870120968, 404.50496651409, 282.627421083333,  84.5780219188797, 284.651787217742, 44.4483895406191, 290.522796125,  0.7227845871322, 295.152023306452, 0, 295.091175080645, 4.495902437649,  285.346147016129, 58.195027213, 279.793625208333, 113.797342811,  275.887160080645, 115.585107734, 276.4884575, 63.46318425,  273.029221741071, 80.4906799595, 274.487727258065, 622.595713923,  278.949141125, 173.082884898, 280.430190080645, 35.560077788,  286.738608583333, 4.61449558, 291.796912903226, 0, 290.786353104839,  26.804723069, 288.891370967742, 43, 283.278972222222, 50.4,  278.910860215054, 63, 280.0725, 33.1, 277.009821428571, 41.8,  279.003400537634, 374.3, 282.647625, 78.4, 284.692096774194,  43.4, 290.523208333333, 0.7, 295.408503184713, 0, 295.108611859838,  4.4, 285.241424731183, 55.83, 279.781638888889, 105.44, 275.904099462366,  83.63, 276.487594086021, 44.66, 272.997767857143, 55.07,  274.421733870968, 428.71, 278.796694444444, 86.12, 280.341102150538,  34.73, 286.669777777778, 4.44, 291.753897849462, 0, 290.652884097035,  26.41), id = c("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", "2",  "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2",  "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2",  "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2",  "2", "2", "2", "2", "2", "2", "2", NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA), RSquared = c(1, 0.998, 1,  0.998, 1, 0.998, 1, 0.998, 1, 0.998, 1, 0.998, 1, 0.998,  1, 0.998, 1, 0.998, 1, 0.998, 1, 0.998, 1, 0.957, 1, 0.957,  1, 0.957, 1, 0.957, 1, 0.957, 1, 0.957, 1, 0.957, 1, 0.957,  1, 0.957, 1, 0.957, 1, 0.957, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.985, 1, 0.985,  1, 0.985, 1, 0.985, 1, 0.985, 1, 0.985, 1, 0.985, 1, 0.985,  1, 0.985, 1, 0.985, 1, 0.985, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA), NSE = c(1, 0.985, 1, 0.985,  1, 0.985, 1, 0.985, 1, 0.985, 1, 0.985, 1, 0.985, 1, 0.985,  1, 0.985, 1, 0.985, 1, 0.985, 1, -0.565, 1, -0.565, 1, -0.565,  1, -0.565, 1, -0.565, 1, -0.565, 1, -0.565, 1, -0.565, 1,  -0.565, 1, -0.565, 1, -0.565, 1, 0.991, 1, 0.991, 1, 0.991,  1, 0.991, 1, 0.991, 1, 0.991, 1, 0.991, 1, 0.991, 1, 0.991,  1, 0.991, 1, 0.991, 1, 0.666, 1, 0.666, 1, 0.666, 1, 0.666,  1, 0.666, 1, 0.666, 1, 0.666, 1, 0.666, 1, 0.666, 1, 0.666,  1, 0.666, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA), PBIAS = c(0, 7.9, 0, 7.9, 0, 7.9, 0, 7.9, 0, 7.9,  0, 7.9, 0, 7.9, 0, 7.9, 0, 7.9, 0, 7.9, 0, 7.9, 0, 84.4,  0, 84.4, 0, 84.4, 0, 84.4, 0, 84.4, 0, 84.4, 0, 84.4, 0,  84.4, 0, 84.4, 0, 84.4, 0, 84.4, 0, 7.1, 0, 7.1, 0, 7.1,  0, 7.1, 0, 7.1, 0, 7.1, 0, 7.1, 0, 7.1, 0, 7.1, 0, 7.1, 0,  7.1, 0, 39.9, 0, 39.9, 0, 39.9, 0, 39.9, 0, 39.9, 0, 39.9,  0, 39.9, 0, 39.9, 0, 39.9, 0, 39.9, 0, 39.9, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), class = c("tbl_df",  "tbl", "data.frame"), row.names = c(NA, -132L))

为绘图准备的标签:

structure(list(Source = c("Observation", "Observation", "Observation", 
"Observation", "Pred1 (wmo correction)", "Pred1 (wmo correction)", 
"Pred1 (wmo correction)", "Pred1 (wmo correction)", "pred2 (Kochendorfer correction)", 
"pred2 (Kochendorfer correction)", "pred2 (Kochendorfer correction)", 
"pred2 (Kochendorfer correction)"), Station = c("PG3", "PG3", 
"PG4", "PG4", "PG3", "PG3", "PG4", "PG4", "PG3", "PG3", "PG4", 
"PG4"), variable = c("precip", "temp", "precip", "temp", "precip", 
"temp", "precip", "temp", "precip", "temp", "precip", "temp"), 
    RSquared = c(NA, NA, NA, NA, 0.998, 1, 0.957, 1, 1, 1, 0.985, 
    1), NSE = c(NA, NA, NA, NA, 0.985, 1, -0.565, 1, 0.991, 1, 
    0.666, 1), PBIAS = c(NA, NA, NA, NA, 7.9, 0, 84.4, 0, 7.1, 
    0, 39.9, 0)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-12L))  

获取每个变量标签的函数:

get_labels <- function(var) {
  labels <- list()
  if (var == "temp") {
    labels$y <- "Temperatur in K"
    labels$title <- "Temperatur"
  } else if (var == "precip") {
    labels$y <- "Niederschlag in mm"
    labels$title <- "Niederschlag"
  } else if (var == "wind_speed") {
    labels$y <- "Windgeschwindigkeit in m/s"
    labels$title <- "Windgeschwindigkeit"
  } else if (var == "rel_hum") {
    labels$y <- "Relative Luftfeuchte in %"
    labels$title <- "Relative Luftfeuchte"
  }
  return(labels)
} 

这里是创建绘图的代码:

  final_plots <- list()
  for (var in variables) {
    filtered_data <- filter(plot_data, variable == var)
    filtered_label <- filter(label_data, variable == var & Source != "Observation")
    labels <- get_labels(var)

    p <- ggplot(data = filtered_data, aes(x = time, y = value, color = Source)) +
      geom_line() +
      geom_text_repel(data = filtered_label, aes(label = paste0("R²:", round(RSquared, 2), ", NSE:", round(NSE, 2), ", PBIAS:", round(PBIAS, 2)), x = min(filtered_data$time), y = Inf,color = Source), size = 2,hjust = -0.1, vjust = 1,show.legend = FALSE) +
      facet_grid(Station ~ ., scales = "free_y") +
      labs(
        title = labels$title,
        x = "Zeit",
        y = labels$y,
        color = "Data Source"
      ) +
      theme_minimal() +
      scale_color_brewer(palette = "Set1") +
      scale_x_datetime(labels = function(x) format(x, "%b %Y"), breaks = "2 month") +
      guides(color = guide_legend(title = "")) +
      theme(
        legend.position = "bottom",
        panel.border = element_rect(color = "black", fill = NA, size = 0.4),
        panel.grid.major = element_line(linetype = "dashed"),
        panel.grid.minor = element_line(linetype = "dashed")
      )

    final_plots[[var]] <- p
  }
r ggplot2 geom-text
1个回答
0
投票

代替使用

geom_text_repel
添加标签,实现所需结果的一种选择是使用
geom_text
geom_label
,其中我使用
vjust
垂直对齐顶部和底部的一个标签。

library(dplyr, warn = FALSE)
library(ggrepel)
#> Loading required package: ggplot2
library(ggplot2)

variables <- c("temp", "precip")

plot_fun <- function(var) {
  filtered_data <- filter(plot_data, variable == var)
  filtered_label <- filter(label_data, variable == var, Source != "Observation")
  labels <- get_labels(var)

  filtered_label <- filtered_label |>
    left_join(
      filtered_data |>
        summarise(
          x = min(time), 
          y = max(value) - .05 * (diff(range(value))),
          .by = Station
        ),
      by = "Station"
    ) |>
    mutate(
      vjust = ifelse(grepl("^Pred1", Source), 0, 1)
    )

  ggplot(data = filtered_data, aes(x = time, y = value, color = Source)) +
    geom_line() +
    geom_label(
      data = filtered_label,
      aes(
        label = paste0(
          "R²:", round(RSquared, 2), ", NSE:", round(NSE, 2),
          ", PBIAS:", round(PBIAS, 2)
        ),
        vjust = vjust,
        color = Source,
        x = x,
        y = y
      ), size = 8 / .pt, hjust = 0, show.legend = FALSE,
      label.size = 0,
      label.padding = unit(2, "pt")
    ) +
    facet_grid(Station ~ ., scales = "free_y") +
    labs(
      title = labels$title,
      x = "Zeit",
      y = labels$y,
      color = "Data Source"
    ) +
    scale_color_brewer(palette = "Set1") +
    scale_x_datetime(labels = function(x) format(x, "%b %Y"), breaks = "2 month") +
    guides(color = guide_legend(title = "")) +
    theme_minimal() +
    theme(
      legend.position = "bottom",
      panel.border = element_rect(color = "black", fill = NA, size = 0.4),
      panel.grid = element_line(linetype = "dashed")
    )
}

final_plots <- lapply(variables, plot_fun)
#> Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
#> ℹ Please use the `linewidth` argument instead.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.

final_plots
#> [[1]]

#> 
#> [[2]]

© www.soinside.com 2019 - 2024. All rights reserved.