基于第二个数据框注释 ggplot

Annotate ggplot based on a second data frame

我有一个用 ggplot 制作的多面图,它已经可以使用了,它显示了河流高度与年份的数据。我正在尝试根据第二个数据框添加箭头,该数据框详细说明了洪水发生的时间。

这是当前的情节:

我想根据第二个数据框中的日期信息在每个图表的顶部绘制箭头,其中每一行对应于洪水并包含一个日期。 两个dataframes之间的link是Station_code这一列,每条河流都有一个或多个站点,由这个数据表示(在这种情况下,只有Var河有两个站点)。

这是用于创建原始图的数据框的dput

structure(list(River = c("Durance", "Durance", "Durance", "Durance", 
"Roya", "Var"), Reach = c("La Brillanne", "Les Mées", "La Brillanne", 
"Les Mées", "Basse vallée", "Basse vallée"), Area_km = c(465, 
465, 465, 465, 465, 465), Type = c("restored", "target", "restored", 
"target", "witness", "restored"), Year = c(2017, 2017, 2012, 
2012, 2018, 2011), Restoration_year = c(2013, 2013, 2013, 2013, 
NA, 2009), Station_code = c("X1130010", "X1130010", "X1130010", 
"X1130010", "Y6624010", "Y6442015"), BRI_adi_moy_sstransect = c(0.00375820736746399, 
0.00244752138003355, 0.00446807607783864, 0.0028792618981479, 
0.00989200896930529, 0.00357247516596474), SD_sstransect = c(0.00165574247612667, 
0.0010044634990875, 0.00220534492332107, 0.00102694633805149, 
0.00788573233793128, 0.00308489160008849), min_BRI_sstransect = c(0.00108123849595469, 
0.00111493913953216, 0.000555500340370182, 0.00100279590198288, 
0, 0), max_BRI_sstransect = c(0.0127781240385231, 0.00700537285706352, 
0.0210216858227621, 0.00815151653110584, 0.127734814926934, 0.0223738711013954
), Nb_sstr_unique_m = c(0.00623321576795815, 0.00259754717331206, 
0.00117035034437559, 0.00209845092352825, 0.0458628969163946, 
3.60620609570031), BRI_adi_moy_transect = c(0.00280232169999531, 
0.00173868254527501, 0.00333818552810438, 0.00181398859573415, 
0.00903651639185542, 0.00447856455432537), SD_transect = c(0.00128472161839638, 
0.000477209421076879, 0.00204050725984513, 0.000472466654940182, 
0.00780731734792112, 0.00310039904793707), min_BRI_transect = c(0.00108123849595469, 
0.00106445386542223, 0.000901992689363725, 0.000855135344651009, 
0.000944414463851629, 0.000162012161197014), max_BRI_transect = c(0.00709151795418251, 
0.00434366293208643, 0.011717024999411, 0.0031991369873946, 0.127734814926934, 
0.0187952134332499), Nb_tr_unique_m = c(0, 0, 0, 0, 0, 0), Error_reso = c(0.0011, 
8e-04, 0.0018, 0.0011, 0.0028, 0.0031), W_BA = c(296.553323029366, 
411.056574923547, 263.944186046512, 363.32874617737, 88.6420798065296, 
158.66866970576), W_BA_sd = c(84.1498544481585, 65.3909073242282, 
100.067554749308, 55.5534084807705, 35.2337070278364, 64.6978349498119
), W_BA_min = c(131, 206, 33, 223, 6, 45), W_BA_max = c(472, 
564, 657, 513, 188, 381), W_norm = c(5.73271228619998, 7.9461900926133, 
5.10234066090722, 7.02355699765464, 5.09378494746752, 4.81262001531126
), W_norm_sd = c(1.62671218635823, 1.2640804493236, 1.93441939783807, 
1.07391043231191, 2.02469218788178, 1.96236658443141), W_norm_min = c(2.53237866910643, 
3.98221378500706, 0.637927450996277, 4.31084307794454, 0.344787822572658, 
1.36490651299098), W_norm_max = c(9.12429566273463, 10.9027600715727, 
12.7005556152895, 9.91687219276031, 10.8033517739433, 11.5562084766569
)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))

这里是包含洪水日期的日期框 dput

structure(list(Station_code = c("Y6042010", "Y6042010", "Y6042010", 
"Y6042010", "Y6042010", "Y6042010"), Date = structure(c(12006, 
12007, 12016, 12017, 13416, 13488), class = "Date"), Qm3s = c(156, 
177, 104, 124, 125, 90.4), Qual = c(5, 5, 5, 5, 5, 5), Year = c(2002, 
2002, 2002, 2002, 2006, 2006), Month = c(11, 11, 11, 11, 9, 12
), Station_river = c("Var@Entrevaux", "Var@Entrevaux", "Var@Entrevaux", 
"Var@Entrevaux", "Var@Entrevaux", "Var@Entrevaux"), River = c("Var", 
"Var", "Var", "Var", "Var", "Var"), Mod_inter = c(13.32, 13.32, 
13.32, 13.32, 13.32, 13.32), Qm3s_norm = c(11.7117117117117, 
13.2882882882883, 7.80780780780781, 9.30930930930931, 9.38438438438438, 
6.78678678678679), File_name = c("Var@Entrevaux.dat", "Var@Entrevaux.dat", 
"Var@Entrevaux.dat", "Var@Entrevaux.dat", "Var@Entrevaux.dat", 
"Var@Entrevaux.dat"), Station_name = c("@Entrevaux", "@Entrevaux", 
"@Entrevaux", "@Entrevaux", "@Entrevaux", "@Entrevaux"), Reach = c("Daluis", 
"Daluis", "Daluis", "Daluis", "Daluis", "Daluis"), Restauration_year = c(2009, 
2009, 2009, 2009, 2009, 2009), `Area_km[BH]` = c(676, 676, 676, 
676, 676, 676), Starting_year = c(1920, 1920, 1920, 1920, 1920, 
1920), Ending_year = c("NA", "NA", "NA", "NA", "NA", "NA"), Accuracy = c("good", 
"good", "good", "good", "good", "good"), Q2 = c(86, 86, 86, 86, 
86, 86), Q5 = c(120, 120, 120, 120, 120, 120), Q10 = c(150, 150, 
150, 150, 150, 150), Q20 = c(170, 170, 170, 170, 170, 170), Q50 = c(200, 
200, 200, 200, 200, 200), Data_producer = c("DREAL_PACA", "DREAL_PACA", 
"DREAL_PACA", "DREAL_PACA", "DREAL_PACA", "DREAL_PACA"), Coord_X_L2e_Z32 = c(959313, 
959313, 959313, 959313, 959313, 959313), Coord_Y_L2e_Z32 = c(1893321, 
1893321, 1893321, 1893321, 1893321, 1893321), Coord_X_L93 = c(1005748.88, 
1005748.88, 1005748.88, 1005748.88, 1005748.88, 1005748.88), 
    Coord_Y_L93 = c(6324083.97, 6324083.97, 6324083.97, 6324083.97, 
    6324083.97, 6324083.97), New_FN = c("Var@Entrevaux.csv", 
    "Var@Entrevaux.csv", "Var@Entrevaux.csv", "Var@Entrevaux.csv", 
    "Var@Entrevaux.csv", "Var@Entrevaux.csv"), NA_perc = c(14.92, 
    14.92, 14.92, 14.92, 14.92, 14.92), Q2_norm = c(6.45645645645646, 
    6.45645645645646, 6.45645645645646, 6.45645645645646, 6.45645645645646, 
    6.45645645645646), Q5_norm = c(9.00900900900901, 9.00900900900901, 
    9.00900900900901, 9.00900900900901, 9.00900900900901, 9.00900900900901
    ), Q10_norm = c(11.2612612612613, 11.2612612612613, 11.2612612612613, 
    11.2612612612613, 11.2612612612613, 11.2612612612613), Q20_norm = c(12.7627627627628, 
    12.7627627627628, 12.7627627627628, 12.7627627627628, 12.7627627627628, 
    12.7627627627628), Q50_norm = c(15.015015015015, 15.015015015015, 
    15.015015015015, 15.015015015015, 15.015015015015, 15.015015015015
    )), row.names = c(NA, -6L), groups = structure(list(Station_code = "Y6042010", 
    .rows = structure(list(1:6), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = 1L, class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

编辑

这是我想在情节上做的一个例子:

这是我目前用来做剧情的代码:

  ggplot(data = tst_formule[tst_formule$River != "Roya",], aes(x = Year, y = BRI_adi_moy_transect, shape = River, col = Type)) +  
  geom_point(size = 3) +    
  geom_errorbar(aes(ymin = BRI_adi_moy_transect - SD_transect, ymax = BRI_adi_moy_transect + SD_transect), size = 0.7, width = 0.3) + 
  geom_errorbar(aes(ymin = BRI_adi_moy_transect - Error_reso, ymax = BRI_adi_moy_transect + Error_reso, linetype = "Error due to resolution"), size = 0.3, width = 0.3, colour = "black") +
  scale_linetype_manual(name = NULL, values = 2) +
  scale_shape_manual(values = c(15, 18, 17, 16)) +
  scale_colour_manual(values = c("chocolate1", "darkcyan")) +  
  new_scale("linetype") +
  geom_vline(aes(xintercept = Restoration_year, linetype = "Restoration"), colour = "chocolate1") + 
  scale_linetype_manual(name = NULL, values = 5) +
  new_scale("linetype") +  
  geom_hline(aes(yintercept = 0.004, linetype = "Threshold"), colour= 'black') + 
  scale_linetype_manual(name = NULL, values = 4) + 
  scale_y_continuous("BRI*", limits = c(min(tst_formule$BRI_adi_moy_transect - tst_formule$SD_transect, tst_formule$BRI_adi_moy_transect - tst_formule$Error_reso ), max(tst_formule$BRI_adi_moy_transect + tst_formule$SD_transect, tst_formule$BRI_adi_moy_transect + tst_formule$Error_reso))) +
  scale_x_continuous(limits = c(min(tst_formule$Year - 1),max(tst_formule$Year + 1)), breaks = scales::breaks_pretty(n = 6)) + 
  theme_bw() + 
  facet_wrap(vars(River)) + 
  theme(legend.spacing.y = unit(-0.01, "cm")) + 
  guides(shape = guide_legend(order = 1),  
         colour = guide_legend(order = 2),
         line = guide_legend(order = 3)) 

经过测试和更多研究,我设法通过在 geom_text() 中添加第二个数据框来做到这一点:

new_scale("linetype") +
  geom_segment(data = Flood_plot, aes(x = Date, xend = Date, y = 0.025, yend = 0.020, linetype = "Morphogenic flood"), arrow = arrow(length = unit(0.2, "cm")), inherit.aes = F, guide = guide_legend(order = 6)) +
  scale_linetype_manual(name = NULL, values = 1) +

new_scale() 在我之前创建的定义之后创建了一个新的 linetype 定义,geom_segment() 允许绘制我想要的箭头,但它适用于 geom_text()scale_linetype_manual() 在图例中绘制箭头,上面没有提到“线型”。第二个数据框与第一个数据框具有相同的列(River)以包装和创建面板。