Chapter 5 Annotations

Annotations are essential for charts because they provide additional context, insights, and information that can help readers better understand the data being presented.

Some of the most important reasons for the use of annotations are around improving accessibility, supporting the narrative and providing contextual information.

  • Annotations like arrows for example help highlight key datapoints or outliers which allow readers to quickly grasp the main message or findings.
  • Annotations that segment the chart using dotted or dashed lines can be really helpful to provide contextual information about the data such as time periods or important/catalyst events.
  • This allows users to better understand changes in a chart since there is a clear narrative behind the changes, especially in time series charts.
  • This doesn’t mean that annotations are limited to lines and arrows. Annotations can be text too.
  • For example, when we want to reinforce a narrative for a chart, text annotations can be used to make the overall presentation more informative and persuasive.
  • Moreover, text annotations can give background information about a chart, such as units of measurement, data sources, or definitions of terms used.
  • In complex charts, annotations can prevent misinterpretations or misunderstandings by guiding readers on how to read the data correctly, ensuring that crucial information doesn’t get overlooked.

Last but not least, annotations enhance readability by reducing the need to refer to external sources for information about the data.

However, it is important to bear in mind that annotations in chart will not be read out by a screen reader. Therefore a someone using a screen reader will miss that information. This is why it’s important to only add necessary annotations, and any information communicated via the annotation must be also be included in the alternative text

Lets now explore how to add different types of annotations.

5.1 Lines

Using lines as annotations allows you to highlight trends or events on the graph.

There are several different ways to plot a segment on a chart. One of the simplest ways is using the geom_segment() function.

The geom_segment() has some simple arguments which make it intuitive to use. The minimum level of information that we need to pass it is coordinates of where the line begins and ends, both on the x and y axis, and as usual, this takes place inside the aes() function. The coordinate could be a string, or a number, or a date. If the coordinate is a date, then you may need to wrap the coordinate in an as.Date() function, eg. x = as.Date("2023-08-15").

Code
geom_segment(aes(x = "", 
                 xend = "", 
                 y = "", 
                 yend = ""), 
             colour = "grey85", linetype = "dashed")
  • x = where along the x axis the line should start from.
  • xend = where along the x axis the line should end.
  • y = where along the y axis the line should start from.
  • yend = where along the y axis the line should end.
  • colour = colour of the line
  • linetype = type of line. Dashed, dotted.

Using this format, you can add as many lines as you need on the chart by layering as many geom_segment() layers as you like.

For the following examples, we will be using this cycling_newham data set, which detailed how often adults cycle in a week between the years 2016 - 2021 for travelling (eg. travelling to work). The data is for the London Borough of Newham.

ONS_Code Area_name Mode Purpose Frequency Year Prop_adults_cycling
E09000025 Newham Cycling Travel At least once per week 2021 6.897274
E09000025 Newham Cycling Travel At least once per week 2020 4.958700
E09000025 Newham Cycling Travel At least once per week 2019 8.732026
E09000025 Newham Cycling Travel At least once per week 2018 5.556300
E09000025 Newham Cycling Travel At least once per week 2017 6.862400
E09000025 Newham Cycling Travel At least once per week 2016 5.113000
Code
ggplot(data = cycling_newham) +
  geom_line(aes(y = Prop_adults_cycling, x = Year, group = Frequency, color = Frequency)) +
  scale_y_continuous(limits = c(0,10), breaks = seq(from = 0, to = 10, by = 2))+
  scale_colour_brewer(palette = "Dark2")+
  line_theme +
  labs(title = "Proportion of adults cycling for travel in Newham per week",
       x = "Year", y = "Proportion of adults")

Lets add some context to this chart by describing the fall in adults cycling in 2020. In this context, it was down to the Covid Lockdown restrictions. We want to draw a straight perpendicular line through the year 2020, so lets begin by passing some arguments through the geom_segment() function.

  • x = "2020" because this is the coordinate where we want the line to begin along the x axis.
  • xend = "2020" because we want it to remain at 2020 along every y coordinate
  • y = 0 because we want it to start at the bottom of the chart
  • yend = 9.5 because we want the line to reach the top of the chart.
  • We can also pass a colour, linewidth and linetype argument to differentiate the line from the actual charting lines on the chart.
Code
ggplot(data = cycling_newham) +
  geom_line(aes(y = Prop_adults_cycling, x = Year, group = Frequency, color = Frequency)) +
  scale_y_continuous(limits = c(0,10), breaks = seq(from = 0, to = 10, by = 2))+
  scale_colour_brewer(palette = "Dark2")+
  line_theme +
  labs(title = "Proportion of adults cycling for travel in Newham per week",
       x = "Year", y = "Proportion of adults")+
   
  # segment 1 at x = 2020 
  geom_segment(aes(x = "2020", 
                   xend = "2020", 
                   y = 9.5, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")

The line gives no information without some text, so lets add some text to the line. We can do this using the annotation() function.

There are many ways to use an annotation function, but to use it for text is very simple. We just need to pass these arguments:

Code
annotate(
  geom = "text"
  x = coordinate,
  y = coordinate,
  size = size of text,
  label = "the text you want on the chart")
Code
ggplot(data = cycling_newham) +
  geom_line(aes(y = Prop_adults_cycling, x = Year, group = Frequency, color = Frequency)) +
  scale_y_continuous(limits = c(0,10), breaks = seq(from = 0, to = 10, by = 2))+
  scale_colour_brewer(palette = "Dark2")+
  line_theme +
  labs(title = "Proportion of adults cycling for travel in Newham per week",
       x = "Year", y = "Proportion of adults")+

##---------------------------------------------------------------- 
##---------------------------------------------------------------- 

  # segment 1 at x = 2020 
  geom_segment(aes(x = "2020", 
                   xend = "2020", 
                   y = 9.5, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  # text at segment             
  annotate("text", 
           x = "2020", 
           y = 10, 
           size = 3,
           label = "National Covid Lockdown")

5.1.1 Excercise

For the exercise we will be using this data and chart:

This dataset is called timeseries_travel_data which shows car travel usage data from April 2020 - December 2021, compared to a pre-covid baseline.

month_year transport date usage
Apr-2020 Cars 2020-04-01 32
Apr-2020 Cars 2020-04-02 32
Apr-2020 Cars 2020-04-03 34
Apr-2020 Cars 2020-04-04 28
Apr-2020 Cars 2020-04-05 25
Apr-2020 Cars 2020-04-06 34
Code
ggplot(data = timeseries_travel_data) +
  geom_line(aes(y = usage, x = date, group = "transport"), linewidth = 0.4)+
  geom_line(aes(y = 100, x= date), linetype = "dashed", colour = "red4") +
  scale_x_date(date_breaks = "3 month", date_labels = "%b-%Y") +
  scale_y_continuous(breaks = seq(from = 0, to = 110, by = 20))+
  labs(title = "Usage of car travel compared to pre-covid baseline",
       x = "Date", y = "Usage")+
  line_theme

10:00

  1. Create 3 segments on the chart for the 3 national lockdowns using the geom_segment() function. The line should begin from y = 0 and either touch or cross the horizontal line at y = 100. Note that the x axis is made up of dates, so your x coordinates will follow this pattern: x = as.Date("yyyy-mm-dd")
  • Segment on 1st April 2020
  • Segment on 1st October 2020
  • Segment on 1st January 2021
Code
ggplot(data = timeseries_travel_data) +
  geom_line(aes(y = usage, x = date, group = "transport"), linewidth = 0.4)+
  geom_line(aes(y = 100, x= date), linetype = "dashed", colour = "red4") +
  scale_x_date(date_breaks = "3 month", date_labels = "%b-%Y") +
  scale_y_continuous(breaks = seq(from = 0, to = 110, by = 20))+
  labs(title = "Usage of car travel compared to pre-covid baseline",
       x = "Date", y = "Usage")+
  line_theme+
  
   
  ##-----------------------------------------------------------
  ##-----------------------------------------------------------
 
  # segment 1 at April 2020 
  geom_segment(aes(x = as.Date("2020-04-01"), 
                   xend = as.Date("2020-04-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
   # segment 2 at October 2020
  geom_segment(aes(x = as.Date("2020-10-01"), 
                   xend = as.Date("2020-10-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
 # segment 3 at January 2021
  geom_segment(aes(x = as.Date("2021-01-01"), 
                   xend = as.Date("2021-01-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")

  ##-----------------------------------------------------------
  ##-----------------------------------------------------------  

5.1.2 Excercise

10:00

  1. Add text annotations for each segment using the annotation() function. Note that the x axis is made up of dates, so your x coordinates will follow this pattern: x = as.Date("yyyy-mm-dd")
  • “1st Lockdown”
  • “2nd Lockdown”
  • “3rd Lockdown”
Code
ggplot(data = timeseries_travel_data) +
  geom_line(aes(y = usage, x = date, group = "transport"), linewidth = 0.4)+
  geom_line(aes(y = 100, x= date), linetype = "dashed", colour = "red4") +
  scale_x_date(date_breaks = "3 month", date_labels = "%b-%Y") +
  scale_y_continuous(breaks = seq(from = 0, to = 110, by = 20))+
  labs(title = "Usage of car travel compared to pre-covid baseline",
       x = "Date", y = "Usage")+
  line_theme+
  
  ##-----------------------------------------------------------
  ##-----------------------------------------------------------
  # segment 1 at April 2020 
  geom_segment(aes(x = as.Date("2020-04-01"), 
                   xend = as.Date("2020-04-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at segment at April 2020             
  annotate("text",
           x = as.Date("2020-04-01"),
           y = 107,
           size = 3,
           label = "1st lockdown")+
  
  ##-----------------------------------------------------------  
  # segment 2 at October 2020
  geom_segment(aes(x = as.Date("2020-10-01"), 
                   xend = as.Date("2020-10-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at segment October 2020            
  annotate("text",
           x = as.Date("2020-10-01"),
           y = 107,
           size = 3,
           label = "2nd lockdown")+
  ##-----------------------------------------------------------
  # segment 3 at January 2021
  geom_segment(aes(x = as.Date("2021-01-01"), 
                   xend = as.Date("2021-01-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at segment October 2020            
  annotate("text",
           x = as.Date("2021-01-01"),
           y = 104,
           size = 3,
           label = "3rd lockdown")

##---------------------------------------------------------------- 
##---------------------------------------------------------------- 

5.2 Text annotations

Text annotations can also be used to make reading a chart easier and more accessible. This is particularly useful when there is a multi-line chart and the only way to read the chart is to associate the category name to the respective line with colour only. However, people that cannot see the colour distinction well will not be able to associate the name of the category to the right line. Therefore labeling the line directly with annotations helps.

We can improve the cycling chart by attaching labels to the lines using the geom_text_repel() function and then get rid of the legend. The geom_text_repel() function works similarly to other geom functions we’ve used in this course, where we supply it some data, and x and y values in the aes() function. The reason why we’re using this function instea dof geom_text() for example, is becasue the ‘repel’ part stands for ‘Repulsive’, meaning the text labels repel away from each other and away from the data points.

There are some preparation steps required to use this function if we want it to map our text appropriately. The prep includes making a separate table of labels and mapping the labels to the right location on the chart. If we use the original dataset, it will plot the labels at all datapoints like this:

So lets begin with prepping our data. An important thing to remember is that what labels you want and where on the chart, will determine how you create your labels datatable.

Our objective for this chart is to create a single set of labels to sit at the end of each line that indicate the frequency of cycling. This means filtering the data down to 3 observations in the year 2021. We can think of this as a labels datatable.

Code
line_labels <- cycling_newham  %>%
      filter(Year == "2021")
ONS_Code Area_name Mode Purpose Frequency Year Prop_adults_cycling
E09000025 Newham Cycling Travel At least once per week 2021 6.8972739
E09000025 Newham Cycling Travel At least 3 times per week 2021 2.8714894
E09000025 Newham Cycling Travel At least 5 times per week 2021 0.9865256

Now that we have a labels datatable, we can plot this information in the chart.

There are many arguments in the geom_text_repel() funtion, and you definitely dont have to use all of them, but they are useful for getting your labels looking nice.

geom_text_repel():

  • data = your labels datatable.
  • aes(x = "", y = "", group = how your lines grouped, label = your label column).
  • segment.color = color of the line connecting the text to the line. Its best to choose "transparent" for this.
  • colour =colour of text.
  • size = size of text.
  • nudge_x = adjust position of text horizontally.
  • nudge_y = adjust position of text vertically.
Code
ggplot(data = cycling_newham) +
  geom_line(aes(y = Prop_adults_cycling, x = Year, group = Frequency, color = Frequency)) +
  scale_y_continuous(limits = c(0,10), breaks = seq(from = 0, to = 10, by = 2))+
  scale_colour_brewer(palette = "Dark2")+
  line_theme +
  theme(legend.position = "none")+
  labs(title = "Proportion of adults cycling for travel in Newham per week",
       x = "Year", y = "Proportion of adults")+
  
##------------------------------------------------------------------------------------------------------
##------------------------------------------------------------------------------------------------------ 
  ## Adding labels here
  geom_text_repel(data = line_labels, aes(x = Year, 
                                          y = Prop_adults_cycling, 
                                          group = Frequency, 
                                          label = Frequency), 
                         colour = "grey8", 
                         segment.color = 'transparent',
                         nudge_x = 1.2, 
                         nudge_y = 0, 
                         size = 3) +
##------------------------------------------------------------------------------------------------------   
##------------------------------------------------------------------------------------------------------  
   
    # segment 1 at x = 2020 
  geom_segment(aes(x = "2020", 
                   xend = "2020", 
                   y = 9.5, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  # text at segment             
  annotate("text", 
           x = "2020", 
           y = 10, 
           label = "Covid Lockdown", 
           size = 3)

5.2.1 Excercise

For this exercise we have a pre-made labels datatable time_series_label that we’re going to use to label the baseline line in our .

month_year transport date usage line_label
Dec-2021 Cars 2021-12-29 73 Baseline

15:00

  1. Plot the time_series_label in the geom_text_repel() function in order to label the baseline. Make x = date and y = usage, and state the column of data you want to use for the label argument.
  2. Is the label not in the location you were hoping? Try swapping out y = usage with y = 100
Code
ggplot(data = timeseries_travel_data) +
  geom_line(aes(y = usage, x = date, group = "transport"), linewidth = 0.4)+
  geom_line(aes(y = 100, x= date), linetype = "dashed", colour = "red4") +
  scale_x_date(date_breaks = "3 month", date_labels = "%b-%Y") +
  scale_y_continuous(breaks = seq(from = 0, to = 110, by = 20))+
  labs(title = "Usage of car travel compared to pre-covid baseline",
       x = "Date", y = "Usage")+
  line_theme+

  
##-----------------------------------------------------------------------    
##-----------------------------------------------------------------------    
## Adding labels here

  geom_text_repel(data = time_series_label, aes(x = date, 
                                          y = 100, 
                                          label = line_label), 
                         colour = "grey8", 
                         segment.color = 'transparent',
                         nudge_x = 7, 
                         nudge_y = 1, 
                         size = 3) +

##---------------------------------------------------------------------
##--------------------------------------------------------------------- 

  # segment 1 at April 2020 
  geom_segment(aes(x = as.Date("2020-04-01"), 
                   xend = as.Date("2020-04-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at April 2020             
  annotate("text",
           x = as.Date("2020-04-01"),
           y = 107,
           size = 3,
           label = "1st lockdown")+
  
  
  # segment 2 at October 2020
  geom_segment(aes(x = as.Date("2020-10-01"), 
                   xend = as.Date("2020-10-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at October 2020            
  annotate("text",
           x = as.Date("2020-10-01"),
           y = 107,
           size = 3,
           label = "2nd lockdown")+
  
  # segment 3 at January 2021
  geom_segment(aes(x = as.Date("2021-01-06"), 
                   xend = as.Date("2021-01-06"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at January 2021           
  annotate("text",
           x = as.Date("2021-01-06"),
           y = 104,
           size = 3,
           label = "3rd lockdown")

5.3 Arrows

Arrows are a brilliant way to help guide the narrative in a chart or point out a key datapoint/change in trend.

Depending on which look you prefer, you can annotate using staright arrows or curved arrows.

A straight arrow is the most straight forward since it can be drawn quite simply using the geom_segment() function again, with some additional arguments. Keep in mind that the type of segment we are drawing this time is different, whereby we don’t want it to cut through lines on the chart, and it probably wont always be perpendicular, hence all x and y values will be different to eachother. And as usual, we can add an annotate function to add some text near the arrow.

geom_segment():

  • x = where along the x axis the line should start from.
  • xend = where along the x axis the line should end.
  • y = where along the y axis the line should start from.
  • yend = where along the y axis the line should end.
  • linewidth = thickness of the line
  • arrow = arrow(length = unit(0.2, "cm"))) - using an arrow function to set the arrow width and unit.
Code
ggplot(data = cycling_newham) +
  geom_line(aes(y = Prop_adults_cycling, x = Year, group = Frequency, color = Frequency)) +
  scale_y_continuous(limits = c(0,10), breaks = seq(from = 0, to = 10, by = 2))+
  scale_colour_brewer(palette = "Dark2")+
  line_theme +
  theme(legend.position = "none")+
  labs(title = "Proportion of adults cycling for travel in Newham per week",
       x = "Year", y = "Proportion of adults")+
  
  ## Adding labels here
  geom_text_repel(data = line_labels, aes(x = Year, 
                                          y = Prop_adults_cycling, 
                                          group = Frequency, 
                                          label = Frequency), 
                         colour = "grey8", 
                         segment.color = 'transparent',
                         nudge_x = 1.5, 
                         nudge_y = 0, 
                         size = 3) +
  
##------------------------------------------------------------------------------------  
##------------------------------------------------------------------------------------ 
  #Adding a straight arrow pointing towards 2019 trend
  geom_segment(aes(x = "2017", 
                   xend = "2018", 
                   y = 9, 
                   yend = 8), 
              linewidth = 0.2,
              color = "grey20", 
              arrow = arrow(length = unit(0.2, "cm")))+
  # Text 
  annotate("text", 
           x = "2017", 
           y = 9.5, 
           size = 3, 
           colour = "grey20", 
           label = "Improved cycling infrastructure in Newham")+
  
##-------------------------------------------------------------------------------------  
##-------------------------------------------------------------------------------------    
    # segment 1 at x = 2020 
  geom_segment(aes(x = "2020", 
                   xend = "2020", 
                   y = 9.5, 
                   yend = 0), 
                   colour = "grey85", 
                   linetype = "dashed")+
  
  # text at segment             
  annotate("text", 
           x = "2020", 
           y = 10, 
           label = "Covid Lockdown", 
           size = 4)

5.3.1 Excercise

15:00

  1. Plot a perpendicular arrow on your chart where:
  • x is 3rd August 2020
  • y = 60
  • yend = 80
  • adjust any other parameter you like
  1. Use an annotation function to add “Eat out to help out scheme” under the arrow.
Code
ggplot(data = timeseries_travel_data) +
  geom_line(aes(y = usage, x = date, group = "transport"), linewidth = 0.4)+
  geom_line(aes(y = 100, x= date), linetype = "dashed", colour = "red4") +
  scale_x_date(date_breaks = "3 month", date_labels = "%b-%Y") +
  scale_y_continuous(breaks = seq(from = 0, to = 110, by = 20))+
  labs(title = "Usage of car travel compared to pre-covid baseline",
       x = "Date", y = "Usage")+
  line_theme+
  
  ## Adding labels here
  geom_text_repel(data = time_series_label, aes(x = date, 
                                          y = 100, 
                                          label = line_label), 
                         colour = "grey8", 
                         segment.color = 'transparent',
                         nudge_x = 7, 
                         nudge_y = 1, 
                         size = 3) +
  
##-----------------------------------------------------------------
##---------------------------------------------------------------- 
## Straight arrow at August 2020

  geom_segment(aes(x = as.Date("2020-08-03"), 
                   xend = as.Date("2020-08-03"), 
                   y = 60, 
                   yend = 80), 
              linewidth = 0.2,
              color = "grey20", 
              arrow = arrow(length = unit(0.2, "cm")))+
  
  annotate("text", 
           x = as.Date("2020-08-10"), 
           y = 56, 
           size = 3, 
           colour = "grey20", 
           label = "Eat out to help out scheme")+

##------------------------------------------------------------------  
##---------------------------------------------------------------- 
  
  # segment 1 at April 2020 
  geom_segment(aes(x = as.Date("2020-04-01"), 
                   xend = as.Date("2020-04-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey85", 
                   linetype = "dashed")+
  
  #  text at April 2020             
  annotate("text",
           x = as.Date("2020-04-01"),
           y = 107,
           size = 3,
           label = "1st lockdown")+
  
  # segment 2 at October 2020
  geom_segment(aes(x = as.Date("2020-10-01"), 
                   xend = as.Date("2020-10-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey85", 
                   linetype = "dashed")+
  
  #  text at October 2020            
  annotate("text",
           x = as.Date("2020-10-01"),
           y = 107,
           size = 3,
           label = "2nd lockdown")+

  # segment 3 at January 2021
  geom_segment(aes(x = as.Date("2021-01-06"), 
                   xend = as.Date("2021-01-06"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey85", 
                   linetype = "dashed")+
  
  #  text at January 2021            
  annotate("text",
           x = as.Date("2021-01-06"),
           y = 104,
           size = 3,
           label = "3rd lockdown")

5.4 Curved Arrow

A curved arrow does the same thing as a straight arrow, but you may prefer this aesthetic.

To create a curved arrow, you can use a geom_curve() function. It’s very similar to how we’ve used the segment function earlier, just a very slight difference.
Some of the arguments that we need to pass through the geom_curve() function:

  • data = your data

  • In the aes() funtion:

     * `x = coordinate`
     * `xend = coordinate`
     * `y = coordinate`
     * `yend = coordinate`
  • linewidth = line thickness

  • curvature = which way you want it to curve

  • arrow = arrow(length = unit(0.2, "cm"))) - arrow function

And as usual, using an annotation function to label the arrow.

Code
ggplot(data = cycling_newham) +
  geom_line(aes(y = Prop_adults_cycling, x = Year, group = Frequency, color = Frequency)) +
  scale_y_continuous(limits = c(0,10), breaks = seq(from = 0, to = 10, by = 2))+
  scale_colour_brewer(palette = "Dark2")+
  line_theme +
  theme(legend.position = "none")+
  labs(title = "Proportion of adults cycling for travel in Newham per week",
       x = "Year", y = "Proportion of adults")+
  
  ## Adding labels here
  geom_text_repel(data = line_labels, aes(x = Year, 
                                          y = Prop_adults_cycling, 
                                          group = Frequency, 
                                          label = Frequency), 
                         colour = "grey8", 
                         segment.color = 'transparent',
                         nudge_x = 1.5, 
                         nudge_y = 0, 
                         size = 3) +

##-----------------------------------------------------------------
##---------------------------------------------------------------- 
## Add curved arrow in 2021
geom_curve(data = cycling_newham, aes(x = "2021", 
                                      y = 8.5, 
                                      xend = "2021", 
                                      yend = 7.5),  
                    curvature = -0.2, 
                    linewidth = 0.2, 
                    colour = "grey8",
                    arrow = arrow(length = unit(0.2, "cm")))+
  
  # Text for curved arrow   
annotate("text", 
          x = "2021", 
          y = 9, 
          size = 3, 
          colour = "grey20", 
          label = "Hybrid working")+
  
##---------------------------------------------------------------- 
##------------------------------------------------------------------  
   
    # segment 1 at x = 2020 
  geom_segment(aes(x = "2020", 
                   xend = "2020", 
                   y = 9.5, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  # text at segment             
  annotate("text", 
           x = "2020", 
           y = 10, 
           label = "Covid Lockdown", 
           size = 4)+

#Straight arrow at pointing at 2019 trend
  
  geom_segment(aes(x = "2017", 
                   xend = "2018", 
                   y = 9, 
                   yend = 8), 
              linewidth = 0.2,
              color = "grey20", 
              arrow = arrow(length = unit(0.2, "cm")))+
  
  annotate("text", 
           x = "2017", 
           y = 9.5, 
           size = 3, 
           colour = "grey20", 
           label = "Improved cycling infrastructure in Newham")

5.4.1 Excercise

15:00

  1. Plot a curved arrow on your chart where:
  • x is 1st Dec 2021
  • xend = 20th Dec 2021,
  • y = 40
  • yend = 55
  • curvature = -0.2
  • add any other arguments you’d like to use
  1. Use an annotation function to add “Omnicron Covid strain” under the arrow.
Code
ggplot(data = timeseries_travel_data) +
  geom_line(aes(y = usage, x = date, group = "transport"), linewidth = 0.4)+
  geom_line(aes(y = 100, x= date), linetype = "dashed", colour = "red4") +
  scale_x_date(date_breaks = "3 month", date_labels = "%b-%Y") +
  scale_y_continuous(breaks = seq(from = 0, to = 110, by = 20))+
  labs(title = "Usage of car travel compared to pre-covid baseline",
       x = "Date", y = "Usage")+
  line_theme+
  
  
  ## Adding labels at lines here
  geom_text_repel(data = time_series_label, aes(x = date, 
                                          y = 100, 
                                          label = line_label), 
                         colour = "grey8", 
                         segment.color = 'transparent',
                         nudge_x = 7, 
                         nudge_y = 1, 
                         size = 3) +
  
  
##----------------------------------------------------------------
##----------------------------------------------------------------   
## Add curved arrow at Dec 2021 
  geom_curve(data = timeseries_travel_data, aes(x = as.Date("2021-12-01"), 
                                      y = 40, 
                                      xend = as.Date("2021-12-20"), 
                                      yend = 55),  
                    curvature = -0.2, 
                    linewidth = 0.2, 
                    colour = "grey8",
                    arrow = arrow(length = unit(0.2, "cm")))+
  
    # Text for curved arrow   
  annotate("text", 
           x = as.Date("2021-12-01"), 
           y = 36, 
           size = 3, 
           colour = "grey20", 
           label = "Omnicron Covid Strain")+
  
##----------------------------------------------------------------
##----------------------------------------------------------------

  # Straight arrow at August 2020
  geom_segment(aes(x = as.Date("2020-08-03"), 
                   xend = as.Date("2020-08-03"), 
                   y = 60, 
                   yend = 80), 
              linewidth = 0.2,
              color = "grey20", 
              arrow = arrow(length = unit(0.2, "cm")))+
  
  # Text for straight arrow
  annotate("text", 
           x = as.Date("2020-08-10"), 
           y = 56, 
           size = 3, 
           colour = "grey20", 
           label = "Eat out to help out scheme")+



  # segment 1 at April 2020 
  geom_segment(aes(x = as.Date("2020-04-01"), 
                   xend = as.Date("2020-04-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at April 2020             
  annotate("text",
           x = as.Date("2020-04-01"),
           y = 107,
           size = 3,
           label = "1st lockdown")+
  
  # segment 2 at October 2020
  geom_segment(aes(x = as.Date("2020-10-01"), 
                   xend = as.Date("2020-10-01"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at October 2020            
  annotate("text",
           x = as.Date("2020-10-01"),
           y = 107,
           size = 3,
           label = "2nd lockdown")+

  # segment 3 at January 2021
  geom_segment(aes(x = as.Date("2021-01-06"), 
                   xend = as.Date("2021-01-06"), 
                   y = 100, 
                   yend = 0), 
                   colour = "grey70", 
                   linetype = "dashed")+
  
  #  text at January 2021           
  annotate("text",
           x = as.Date("2021-01-06"),
           y = 104,
           size = 3,
           label = "3rd lockdown")