0

I want to add a few texts in one facet out of four facets in my ggplot.

I am using annotate function to add a text but it generates the text at a given location (x,y) in every facet. Because the data variables have different ranges of y in each facet, the texts are not coming at a desired location (x,y).

Please let me know what should be done. Thanks.

library(dplyr)
library(tidyr)
library(ggplot2)

df%>%
  select(Date, Ca, Na, K, Mg)%>%
  gather(var,value,-Date)%>%
  ggplot(aes(as.Date(Date), value))+
  geom_point()+
  theme_bw()+
  facet_wrap(~var,scales = 'free_y',ncol = 1)+
  ylab("       (ppm)                    (ppm)                   
         (ppm)                    (ppm)")+
  facet_wrap(~var,scales = 'free_y',ncol = 1, strip.position = "right")+
  geom_vline(aes(xintercept = as.Date("2021-04-28")), col = "red")+
  geom_vline(aes(xintercept = as.Date("2021-04-28")), col = "red")+
  geom_vline(aes(xintercept = as.Date("2021-04-29")), col = "red")+
  theme(axis.title = element_text(face="bold"))+
  theme(axis.text = element_text(face="bold"))+
  xlab('Date')+
  theme(axis.title.x = element_text(margin = margin(t = 10)))+
  theme(axis.title.y = element_text(margin = margin(r = 10)))+
  annotate("text", label = "E1", x = as.Date("2021-04-28"), y = 2.8)

This is the code I am using for the desired output. I want to name all the xintercept lines which is E1, E2, E3 (from left to right) on the top of xaxis i.e. above the first facet of variable Ca in the data. Any suggestions?

Here is a part of my data:

df <- read.table(text = "
            Date    Ca  K   Mg  Na
         2/18/2021  1   25  21  19
         2/22/2021  2   26  22  20
         2/26/2021  3   27  23  21
         3/4/2021   4   28  5   22
         3/6/2021   5   29  6   8
         3/10/2021  6   30  7   9
         3/13/2021  7   31  8   10
         3/17/2021  8   32  9   11
         3/20/2021  9   33  10  12
         3/23/2021  10  34  11  13
         3/27/2021  11  35  12  14
         3/31/2021  12  36  13  15
         4/3/2021   13  37  14  16
         4/7/2021   14  38  15  17
         4/10/2021  15  39  16  18
         4/13/2021  16  40  17  19
         4/16/2021  17  41  18  20
         4/19/2021  8   42  19  21
         4/22/2021  9   43  20  22
         4/26/2021  0   44  21  23
         4/28/2021  1   45  22  24
         4/28/2021  2   46  23  25
         4/28/2021  3   47  24  26
         4/28/2021  5   48  25  27
         4/29/2021  6   49  26  28
         5/4/2021   7   50  27  29
         5/7/2021   8   51  28  30
         5/8/2021   9   1   29  31
         5/10/2021  1   2   30  32
         5/29/2021  3   17  43  45
         5/31/2021  6   18  44  46
         6/1/2021   4   19  45  47
         6/2/2021   8   20  46  48
         6/3/2021   2   21  47  49
         6/7/2021   3   22  48  50
         6/10/2021  5   23  49  51
         6/14/2021  3   5   50  1
         6/18/2021  1   6   51  2
", header = TRUE)
zx8754
  • 52,746
  • 12
  • 114
  • 209

1 Answers1

1

Prepare the data before plotting, make a separate data for text annotation:

dfplot <- df %>%
  select(Date, Ca, Na, K, Mg) %>%
  #convert to date class before plotting
  mutate(Date = as.Date(Date, "%m/%d/%Y")) %>%
  #using pivot instead of gather. gather is superseded.
  #gather(var, value, -Date)
  pivot_longer(cols = 2:5, names_to = "grp", values_to = "ppm")
  
dftext <- data.frame(grp = "Ca", # we want text to show up only on "Ca" facet.
  ppm = max(dfplot[ dfplot$grp == "Ca", "ppm" ]),
  Date = as.Date(c("2021-04-27", "2021-04-28", "2021-04-29")),
  label = c("E1", "E2", "E3"))

After cleaning up your code, we can use geom_text with dftext:

ggplot(dfplot, aes(Date, ppm)) +
  geom_point() +
  facet_wrap(~grp, scales = 'free_y',ncol = 1, strip.position = "right") +
  geom_vline(xintercept = dftext$Date, col = "red") +
  geom_text(aes(x = Date, y = ppm, label = label), data = dftext, nudge_y = -2)

enter image description here

Try using ggrepel library to avoid label overlap, replace geom_text with one of these:

  #geom_text_repel(aes(x = Date, y = ppm, label = label), data = dftext)
  #geom_label_repel(aes(x = Date, y = ppm, label = label), data = dftext)

enter image description here

After cleaning up the code and seeing the plot, I think this post is a duplicate of Annotation on only the first facet of ggplot in R? .

zx8754
  • 52,746
  • 12
  • 114
  • 209