Adding geom_label to existing plot

Hi,

I'd like to add text to an existing time series plot. The code I used to create the chart is as follows:

```ggplot(MI_FL_Data, aes(x=realdate, y=FLday))+geom_area(fill="blue")+labs(x=NULL, y="Number of Daily COVID Cases", title="Florida ")

where x is the date and y is the number of cases each day. Now I'd like to add points where the governor declared actions (this variable is called FL_ClosingActions) and is text. I believe the correct way to do this is to add to the above code

+layer (geom_text)(aes(x=FL_ClosingActions, colour="red") 

but I get an Error message: Attempted to create a layer with no stat. Does this mean I need to add (geom_point) somewhere in the code? I'm at a loss and this seems like it should be fairly simple. Any assistance is appreciated.

Here is a very simple example. The x and y positions of the labels are inherited from the aes() in the ggplot() function. You could independently set them in the aes() of geom_text().

library(ggplot2)

DF <- data.frame(X=1:4,Y=1:4,word=LETTERS[1:4])

ggplot(DF, aes(X,Y)) + geom_area(fill="blue") +
  geom_text(aes(label = word), vjust=0)

This worked, however now I need to provide a legend explaining what the code labels mean (here 1 indicates closing and 2 indicates opening policies). I've attached the image so you can see what I mean. I assume I can add hjust=1 to float the numbers above the data a bit?

ggplot(MI_FL_Data, aes(x=realdate, y=FLday))+geom_area(fill="blue")+labs(x=NULL, y="Number of Daily COVID Cases", title="State of Florida")+geom_text(aes(label=FL_Actions), vjust=0) ```

![FL_Data|647x479](upload://h7Pw6nP6KADlO2cgvqTl045six2.jpeg)

Can you post a bit of your data? One way to do that is to post the output of dput. Something like

dput(head(MI_FL_Data, 15))

That will provide 15 rows of data. You can adjust the number of lines to provide enough data to show a minimal example of what you need. Please place the output between two lines that contain only three back ticks.
```
Your output here
```

structure(list(Date = c("1/22/20", "1/23/20", "1/24/20", "1/25/20", 
"1/26/20", "1/27/20", "1/28/20", "1/29/20", "1/30/20", "1/31/20", 
"2/1/20", "2/2/20", "2/3/20", "2/4/20", "2/5/20"), Date2 = c("1/22/20", 
"1/23/20", "1/24/20", "1/25/20", "1/26/20", "1/27/20", "1/28/20", 
"1/29/20", "1/30/20", "1/31/20", "2/1/20", "2/2/20", "2/3/20", 
"2/4/20", "2/5/20"), Date3 = c("1/22/20", "1/23/20", "1/24/20", 
"1/25/20", "1/26/20", "1/27/20", "1/28/20", "1/29/20", "1/30/20", 
"1/31/20", "2/1/20", "2/2/20", "2/3/20", "2/4/20", "2/5/20"), 
    FLORIDA = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L), FLday = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L), MICHIGAN = c(0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), MIday = c(0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), FL_Actions = c(NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_), MI_Actions = c(NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_, NA_integer_, NA_integer_, NA_integer_), realdate = structure(c(18283, 
    18284, 18285, 18286, 18287, 18288, 18289, 18290, 18291, 18292, 
    18293, 18294, 18295, 18296, 18297), class = "Date")), row.names = c(NA, 
15L), class = "data.frame")```

Here you go.

In the data you posted all of the FL_actions are NA so there is nothing for geom_text to plot. Is that the column that should have values of 1 and 2? Are there NA values between the 1 and 2?

Policy actions don’t come until later in the year which is why you don’t seem them. First closing actions do not occur until March. If there’s a way to use the code to get a different cut of the data I can repost another selection.

You can find the row numbers where FL_Actions is not NA with the command

which(!is.na(MI_FL_Data$FL_Actions))

You can get a sequence of rows, say 57 - 72 with

Smpl <- MI_FL_Data[57:72, ]

or you can get discontinuous blocks by combining ranges inside of the c() function

Smpl <- MI_FL_Data[c(57:65, 89:97), ]

Pick whatever works with your data to reproduce what you are trying to graph.

It turns out my co-author wants a slightly differnt look to this chart. Basically, he'd like a geom_hline at the top of the time series with FL_Actions plotted on (one for closing actions which is coded=1, and one for opening actions which coded 2). I got so far as getting the hlines in the right places and in the right colors, but when I add the FL_Actions they are being applied to the time series, not the hline. Any ideas? Here's the code:

ggplot(MI_FL_Data, aes(realdate, FLday))+geom_hline(aes(yintercept = 15000), data=MI_FL_Data, colour="red")+geom_hline(aes(yintercept=17000), data=MI_FL_Data, colour="green")+geom_text(aes(label=FL_Actions))+geom_line()+labs(x=NULL, y="Number of Reported Daily COVID Cases", title="State of Florida")+theme_classic()

Here's a link to the data if you'd like to see: Raw Data Thanks for your assistance, I know I'm almost there but ggplots always confuses me with the layering!! Almost_Florida|550x476

If you want points to appear on the hline, you have to do that with geom_point. Set the y of geom_point to the same value as the yintercept of geom_hline and set the x of geom_point to the column that holds the appropriate date values.

1 Like

Ok, I keep getting an error. Column 8 (FL_Action) has the 1,2 coding (along with NA since there were many dates without actions), but when I type the code:
ggplot(MI_FL_Data, aes(realdate, FLday))+geom_line()+geom_hline(aes(yintercept = 15000), data=MI_FL_Data, linetype=2)+geom_hline(aes(yintercept=17000), data=MI_FL_Data, linetype=4)+geom_point(aes(col=8, 15000))+geom_point(aes(col=8,17000))+labs(x=NULL, y="Number of Reported Daily COVID Cases", title="State of Florida")+theme_classic()

I get an error that says: Error: Invalid input: date_trans works with objects of class Date only. I think I need to add the realdate (I used library(lubridate) to create this new variable, but want only dates that are coded 1 to go one 1 line and those coded 2 to go on the other. Would this look something like:
geom_point(aes(realdate, col=8 if.1) yintercept 17000) or something like that?

Apologies for continuing to bug you! I appreciate your help!