我有一个ggplot,为5个站点中的每个站点绘制了3个数据点.我根据现场对线和点进行了 colored颜色 编码.然后我绘制每个站点的平均值并进行 colored颜色 匹配,但将线设为虚线.我想在每个地点的说明中添加一条虚线,并在说明中的每个实心线下添加相应的 colored颜色 .

数据

chl_no_est <- structure(list(sample_date = structure(c(1683763200, 1683763200, 
1683676800, 1683676800, 1683676800, 1689206400, 1689206400, 1689120000, 
1689120000, 1689120000, 1694649600, 1694649600, 1694563200, 1694649600, 
1694563200), tzone = "America/Los_Angeles", class = c("POSIXct", 
"POSIXt")), event = c("May 2023", "May 2023", "May 2023", "May 2023", 
"May 2023", "July 2023", "July 2023", "July 2023", "July 2023", 
"July 2023", "September 2023", "September 2023", "September 2023", 
"September 2023", "September 2023"), station_name = c("TMDL-R1", 
"TMDL-R2", "TMDL-CL", "TMDL-R3", "TMDL-R4", "TMDL-R1", "TMDL-R2", 
"TMDL-CL", "TMDL-R3", "TMDL-R4", "TMDL-R1", "TMDL-R2", "TMDL-CL", 
"TMDL-R3", "TMDL-R4"), var = c("Chlorophyll a", "Chlorophyll a", 
"Chlorophyll a", "Chlorophyll a", "Chlorophyll a", "Chlorophyll a", 
"Chlorophyll a", "Chlorophyll a", "Chlorophyll a", "Chlorophyll a", 
"Chlorophyll a", "Chlorophyll a", "Chlorophyll a", "Chlorophyll a", 
"Chlorophyll a"), result = c(8.86, 41.3, 8.01, 10.5, 112, 53.2, 
81.7, 61.9, 74.5, 103, 108, 53.3, 10.6, 27.8, 24.4), mean_var = c(56.6866666666667, 
58.7666666666667, 26.8366666666667, 37.6, 79.8, 56.6866666666667, 
58.7666666666667, 26.8366666666667, 37.6, 79.8, 56.6866666666667, 
58.7666666666667, 26.8366666666667, 37.6, 79.8)), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -15L), groups = structure(list(
    station_name = c("TMDL-CL", "TMDL-R1", "TMDL-R2", "TMDL-R3", 
    "TMDL-R4"), .rows = structure(list(c(3L, 8L, 13L), c(1L, 
    6L, 11L), c(2L, 7L, 12L), c(4L, 9L, 14L), c(5L, 10L, 15L)), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -5L), .drop = TRUE))



dry_season_1year_events <- data.frame(event = c("May 2023", "June 2023", "July 2023", "August 2023", "September 2023"))


代码

annotation_mean_chl <- chl_no_est %>% 
  select(event, station_name, result) %>% 
  group_by(station_name) %>% 
  mutate(avg_result = mean(result))
  


chl_no_est$event <- factor(chl_no_est$event, levels = dry_season_1year_events$event)


annotation_chl <- data.frame(
   x = c("May 2023"),
   y = c(158),
   label = c("Target Seasonal Average: 150 mg/m2")
)



ggplot() +
  geom_line(data = chl_no_est, aes(x = event, y = result, color = station_name, group = station_name), size = 0.8) +
  geom_point(data = chl_no_est, aes(x = event, y = result, color = station_name, group = station_name)) +
  theme_classic() +
  geom_hline(yintercept = c(150), linetype = "solid", color = "black", size = 0.7) +
  geom_line(data = annotation_mean_chl, aes(x=event, y=avg_result, color = station_name, group = station_name), linetype=2) +
  scale_color_viridis(discrete = TRUE, name = NULL) +
  theme(plot.title = element_text(hjust = 0.5),
        axis.title.x = element_blank(),
        legend.position = "bottom",  # Place legend under the x-axis
        legend.box = "horizontal",
        panel.grid.major.y = element_line(size=.01, color="grey60" )) +
  labs(y="Chlorophyll a (mg/m2)") +
  scale_y_continuous(limits = c(0, 200), breaks = seq(0, 200, by = 20),
                     expand = c(0,0)) +
  geom_text(data = annotation_chl, aes(x=x, y=y, label=label), nudge_x = 0.1)

Needs Dashed Lines on Legend

没有,不确定如何继续.

推荐答案

一个快速简单的 Select 是使用ggnewscale包为平均虚线添加第二个 colored颜色 等级.

library(ggplot2)
library(viridis)

ggplot() +
  geom_line(data = chl_no_est, aes(x = event, y = result, color = station_name, group = station_name), size = 0.8) +
  geom_point(data = chl_no_est, aes(x = event, y = result, color = station_name, group = station_name)) +
  geom_hline(yintercept = c(150), linetype = "solid", color = "black", linewidth = 0.7) +
  geom_text(data = annotation_chl, aes(x = x, y = y, label = label), nudge_x = 0.1) +
  scale_color_viridis(
    discrete = TRUE, name = NULL,
    guide = guide_legend(order = 1)
  ) +
  ggnewscale::new_scale_color() +
  geom_line(data = annotation_mean_chl, aes(
    x = event, y = avg_result,
    color = station_name,
    group = station_name,
  ), linetype = 2) +
  scale_color_viridis(
    discrete = TRUE, name = NULL,
    guide = guide_legend(order = 2)
  ) +
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5),
    axis.title.x = element_blank(),
    legend.position = "bottom",
    legend.box = "vertical",
    legend.direction = "horizontal",
    panel.grid.major.y = element_line(size = .01, color = "grey60"),
    legend.margin = margin()
  ) +
  labs(y = "Chlorophyll a (mg/m2)") +
  scale_y_continuous(
    limits = c(0, 200), breaks = seq(0, 200, by = 20),
    expand = c(0, 0)
  )

enter image description here

一种更详细的方法是使用自定义按键按钮功能,该功能组合了两个segmentsGrob和一个pointsGrob来消除重复的标签.(下面的代码只是一个剥离的 draw_key_pathdraw_key_point的向下版本.)此外,这需要为geom_point和第二个geom_line设置show.legend=FALSE:

draw_key_cust <- function(data, params, size) {
  if (is.null(data$linetype)) {
    data$linetype <- 0
  } else {
    data$linetype[is.na(data$linetype)] <- 0
  }
  grob1 <- grid::segmentsGrob(
    0.1, 0.75, 0.9, 0.75,
    gp = grid::gpar(
      col = data$colour,
      lwd = .8 * .pt,
      lty = 1
    )
  )

  grob2 <- grid::segmentsGrob(
    0.1, 0.25, 0.9, 0.25,
    gp = grid::gpar(
      col = data$colour,
      lwd = .7 * .pt,
      lty = 2
    )
  )

  data$shape <- 19
  stroke_size <- data$stroke %||% 0.5
  stroke_size[is.na(stroke_size)] <- 0
  grob3 <- grid::pointsGrob(0.5, 0.75,
    pch = data$shape,
    gp = grid::gpar(
      col = data$colour,
      fontsize = 1.5 * .pt + stroke_size * .stroke / 2,
      lwd = stroke_size * .stroke / 2
    )
  )

  grid::gList(
    grob1,
    grob2,
    grob3
  )
}

ggplot(chl_no_est, aes(x = event, y = result, color = station_name, group = station_name)) +
  geom_line(
    linewidth = 0.8,
    key_glyph = "cust"
  ) +
  geom_point(
    show.legend = FALSE
  ) +
  geom_hline(yintercept = c(150), linetype = "solid", color = "black", linewidth = 0.7) +
  geom_text(
    data = annotation_chl, aes(x = x, y = y, label = label), nudge_x = 0.1,
    inherit.aes = FALSE
  ) +
  scale_color_viridis(
    discrete = TRUE, name = NULL,
    guide = guide_legend(order = 1)
  ) +
  geom_line(data = annotation_mean_chl, aes(
    y = avg_result
  ), linetype = 2, show.legend = FALSE) +
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5),
    axis.title.x = element_blank(),
    legend.position = "bottom",
    legend.box = "vertical",
    legend.direction = "horizontal",
    panel.grid.major.y = element_line(size = .01, color = "grey60"),
    legend.margin = margin()
  ) +
  labs(y = "Chlorophyll a (mg/m2)") +
  scale_y_continuous(
    limits = c(0, 200), breaks = seq(0, 200, by = 20),
    expand = c(0, 0)
  )

enter image description here

R相关问答推荐

使用%in%时如何应用多个条件?

在R中,如何创建时间间隔的图表?

卸载安装了BRM的模型发出的警告

更改Heatmap Annotation对象的名称

多重RHS固定估计

如何删除gggvenn与gggplot绘制的空白?

在"gt"表中添加第二个"groupname_col",而不连接列值

R for循环返回到先前值

如何优化向量的以下条件赋值?

制作等距离的线串副本

多个过滤器内的一个盒子在仪表板Quarto

从一个列表的框架中移除列表包装器

在数据帧列表上绘制GGPUP

从多层嵌套列表构建Tibble?

如何创建累加到现有列累计和的新列?

为什么这个表格格罗布不打印?

多元正态分布的计算

有没有办法将不等长的列表转换为R中的数据帧

如何移动点以使它们的打印不重叠

如何使投篮在R中保持一致