In this post, we will work towards creating the line plot below.

The post will take you from a basic line plot and explain all the customization we add to the code step-by-step.

In this chapter, we will learn to:

** build simple line chart

** modify line properties, including type, color, and size

** create grouped line chart

library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.3     v purrr   0.3.4
## v tibble  3.0.5     v dplyr   1.0.3
## v tidyr   1.1.2     v stringr 1.4.0
## v readr   1.4.0     v forcats 0.5.0
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(ggplot2)
library(ggtext)
## Warning: package 'ggtext' was built under R version 4.0.5
library(cowplot)
## Warning: package 'cowplot' was built under R version 4.0.5

Example: Average sale price of detached home in Toronto

Loading data

data <- read_csv("gta_realestate.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   city = col_character(),
##   year = col_double(),
##   type = col_character(),
##   price = col_double()
## )
head(data,10)
## # A tibble: 10 x 4
##    city     year type            price
##    <chr>   <dbl> <chr>           <dbl>
##  1 Toronto  2011 detached home  701846
##  2 Toronto  2012 detached home  722393
##  3 Toronto  2013 detached home  864351
##  4 Toronto  2014 detached home  934039
##  5 Toronto  2015 detached home 1039638
##  6 Toronto  2016 detached home 1286605
##  7 Toronto  2017 detached home 1250235
##  8 Toronto  2018 detached home 1145892
##  9 Toronto  2019 detached home 1363357
## 10 Toronto  2020 detached home 1475758
df <- data %>% 
  filter(type == "detached home" & city == "Toronto") %>% 
  mutate(year = as.factor(year))
df
## # A tibble: 10 x 4
##    city    year  type            price
##    <chr>   <fct> <chr>           <dbl>
##  1 Toronto 2011  detached home  701846
##  2 Toronto 2012  detached home  722393
##  3 Toronto 2013  detached home  864351
##  4 Toronto 2014  detached home  934039
##  5 Toronto 2015  detached home 1039638
##  6 Toronto 2016  detached home 1286605
##  7 Toronto 2017  detached home 1250235
##  8 Toronto 2018  detached home 1145892
##  9 Toronto 2019  detached home 1363357
## 10 Toronto 2020  detached home 1475758

1. Creating a basic line plot

The main function here is geom_line()

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line() +
  theme_minimal()

At this stage, I would like to show you how to modify graph using ggplot2. There will be other posts will focus on improve the aesthetic of the image.

ggsave("Figure 1.Basic line graph using geom_line.png", height = 3, width = 5,units = "in",dpi = 300)

Alternatively, we can also use geom_path()

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_path() +
  theme_minimal()

ggsave("Figure 2.Basic line graph using geom_path.png", height = 3, width = 5,units = "in",dpi = 300)

2. Change line properties

2.1 size

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line(size = 1) +
  theme_minimal()

ggsave("Figure 3.Customize line size.png", height = 3, width = 5,units = "in",dpi = 300)

2.2. Type

The line type can be modified using the linetype argument. It can take 7 different values.

We can specify the line type either using numbers or words as shown below:

0 : blank

1 : solid

2 : dashed

3 : dotted

4 : dotdash

5 : longdash

6 : twodash

2.2.1. using words

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line(linetype = "dashed", size = 1) +
  theme_minimal()

ggsave("Figure 4.Customize line type using words.png", height = 3, width = 5,units = "in",dpi = 300)

2.2.2. using number

Here the number 4 corresponds to “dotdash”.

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line(linetype = 4, size = 1) +
  theme_minimal()

ggsave("Figure 5.Customize line type using number.png", height = 3, width = 5,units = "in",dpi = 300)

2.3 Changing colors

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line(color = "blue", size =1, linetype ="longdash") +
  theme_minimal()

ggsave("Figure 6.Customize color.png", height = 3, width = 5,units = "in",dpi = 300)

2.4 Adding points to the line

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line() +
  geom_point() + # changing size and color of the point
  theme_minimal()

ggsave("Figure 7.Adding points.png", height = 3, width = 5,units = "in",dpi = 300)

2.4.1. changing size and color of the point

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line() +
  geom_point(size = 5, color = "purple") + 
  theme_minimal()

ggsave("Figure 8.Customize color of points.png", height = 3, width = 5,units = "in",dpi = 300)

2.4.2. changing the shape

ggplot(data= df,
       aes(x = year, y = price, group= 1)) +
  geom_line() +
  geom_point(size = 3, color = "blue", shape=23) + 
  theme_minimal()

ggsave("Figure 9.Customize shape of points.png", height = 3, width = 5,units = "in",dpi = 300)

2.4.3. changing filing color

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line() +
  geom_point(size = 3, color = "blue", shape=23, fill= "purple") + 
  theme_minimal()

ggsave("Figure 10.Customize color of points.png", height = 3, width = 5,units = "in",dpi = 300)

2.4.4.Adding labels

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line() +
  geom_point(size = 2, color = "blue",fill= "blue", shape=21) + 
  geom_text(data= df, aes(x = year, y = price, group = 1,
                          label= paste("$",round(price/1000000,2),"M")),
            color = "blue", 
            vjust = 2.5)+
  scale_y_continuous(expand =  c(0,0),
                     limits = c(500000,1500000),
                     n.breaks = 5) +
  theme_minimal() +
  theme(axis.title = element_text(size =12),
        axis.text = element_text(size =12))

ggsave("Figure 11A.Adding labels.png", height = 5, width = 8,units = "in",dpi = 300)

Note: We can customize labels. For example, we want to compares only the data of 2011 and 2020.

ggplot(data= df,
       aes(x = year, y = price, group = 1)) +
  geom_line() +
  geom_point(size = 3, color = "blue",fill= "blue", shape=21) + 
  geom_text(data= df %>% 
              filter(year == 2011 | year == 2020), # to label only the data point at 2011 and 2020 only
            aes(x = year, y = price, 
                group = 1,
                label= paste("$",round(price/1000000,2),"M")),
            color = "blue", 
            vjust =2.5)+
  scale_y_continuous(expand =  c(0,0),
                     limits = c(500000,1500000),
                     n.breaks = 5) +
  theme_minimal() +
  theme(axis.title = element_text(size =12),
        axis.text = element_text(size =12))

(There will be a post dedicated to labels)

ggsave("Figure 11B.Adding labels.png", height = 5, width = 8,units = "in",dpi = 300)

3. Multiple lines

Example: We would like to see the change of detached homes in three cities: Toronto, Brampton, and Scarborough.

Data preparation

df <- data %>% 
  filter(type == "detached home") %>% 
  mutate(year = as.factor(year),
         city = as.factor(city))

To display multiple lines, you can use the group attribute in the data aesthetics layer.

3.1. Basic line chart

ggplot() +
  geom_line(data = df,
            aes(x= year, y = price, 
                group = city), # to draw multiple lines, we need to use group here
            size = 1.5) 

ggsave("Figure 12.Create multiple lines.png", height = 3, width = 5,units = "in",dpi = 300)

In order to distinguish these three lines, we have to map them with color.

ggplot() +
  geom_line(data = df,
            aes(x= year, y = price, 
                group = city, # 
                color = city), # three line by three default color
            size = 1.5) +
  theme(axis.title = element_text(size =12),
        axis.text = element_text(size =12))#  increase the size of the line

The three colors here are default colors.

When applying color for three line, the legend will automatically created

ggsave("Figure 13.Adding color to lines.png", height = 5, width = 8,units = "in",dpi = 300)

geom_path() connects the observations in the order in which they appear in the data.

geom_line() connects them in order of the variable on the x axis.

3.2. Customize color of the line

we can change manually line colors using the functions :

scale_color_manual() : to use custom colors

scale_color_brewer() : to use color palettes from RColorBrewer package

scale_color_grey() : to use grey color palettes

3.2.1. scale_color_manual()

3.2.1.1. using color codes

ggplot() +
  geom_line(data = df,
            aes(x= year, y = price, 
                group = city, # 
                color = city), # three line by three default color
            size = 1.5) + #  increase the size of the line +
 scale_colour_manual(values=c("#6495ED", "#808000", "#000080"))  +
  theme_minimal() +
  theme(axis.title = element_text(size =12),
        axis.text = element_text(size =12))

ggsave("Figure 14A.Customize colors using scale_colour_manual().png", height = 5, width = 8,units = "in",dpi = 300)

3.2.1.2. using words

ggplot() +
  geom_line(data = df,
            aes(x= year, y = price, 
                group = city, # 
                color = city), # three line by three default color
            size = 1.5) + #  increase the size of the line +
 scale_colour_manual(values=c("red", "darkgreen", "orange"))  +
  theme_minimal() +
  theme(axis.title = element_text(size =12),
        axis.text = element_text(size =12))

ggsave("Figure 14B.Customize colors using scale_colour_manual().png", height = 5, width = 8,units = "in",dpi = 300)

3.2.2. scale_color_brewer()

ggplot() +
  geom_line(data = df,
            aes(x= year, y = price, 
                group = city, # 
                color = city), # three line by three default color
            size = 1.5) + #  increase the size of the line +
 scale_color_brewer(palette = "Set1") +
  theme_minimal() +
  theme(axis.title = element_text(size =12),
        axis.text = element_text(size =12))

ggsave("Figure 15.Customize colors using scale_color_brewer().png", height = 5, width = 8,units = "in",dpi = 300)

See https://ggplot2.tidyverse.org/reference/scale_brewer.html for more information about scale_color_brewer

3.2.3. scale_color_grey()

ggplot() +
  geom_line(data = df,
            aes(x= year, y = price, 
                group = city, # 
                color = city), # three line by three default color
            size = 1.5) + #  increase the size of the line +
 scale_color_grey() +
  theme_minimal() +
  theme(axis.title = element_text(size =12),
        axis.text = element_text(size =12))

ggsave("Figure 16.Customize colors using scale_color_grey().png", height = 5, width = 8,units = "in",dpi = 300)

3.3. Set line types manually

You must map a column in your data to the linetype aesthetic and then assign linetypes to the values of that column.

ggplot() +
  geom_line(data = df,
            aes(x= year, y = price, 
                group = city,
                color = city,
                linetype = city), 
            size = 1.5) + #  increase the size of the line +
  scale_colour_manual(values=c("#6495ED", "#808000", "#000080")) +
  scale_linetype_manual(values=c("dotted","dotted","solid")) +
  theme_minimal() +
  theme(axis.title = element_text(size =12),
        axis.text = element_text(size =12))

ggsave("Figure 17.Customize line types using scale_linetype_manual().png", height = 5, width = 8,units = "in",dpi = 300)

see https://ggplot2.tidyverse.org/reference/scale_linetype.html for more information

4. The final graphe

Applying all the steps above, we can obtain the following graph.

ggplot() +
  geom_line(data = df,
            aes(x= year, y = price, group = city, color = city),
            size = 1.5) + 
  scale_y_continuous(expand =  c(0,0),
                     limits = c(0,1500000),
                     n.breaks = 6) +
  scale_colour_manual(values=c("#6495ED", "#808000", "#1F497D"))  +
  geom_text(data = df %>% filter(year == 2020),
            aes(x = year,y = price, color = city, label = city), 
            nudge_x = 0.3,
            hjust =0,
            size = 4) +
  labs(title = "Average sale price for detached homes (Dec.2011-Dec.2020)", 
       # subtitle = "The cost of owning a home has more than doubled across GTA since the end of 2011",
         caption = "Data source: Toronto Regional Real Estate Board ",
         x = "Year",
         y = "Average price sale (CAD)") +
  coord_cartesian(clip = 'off') + 
  theme(plot.title = element_markdown(size=14, margin=margin(0,0,30,0),face="bold"),
        plot.subtitle = element_markdown(size=12, margin=margin(0,0,15,0)),
        plot.title.position = "plot",
        plot.caption = element_text(hjust = 0),
        plot.caption.position =  "plot",
        axis.title.x= element_text(size = 11, hjust = 0, vjust = 0, color = "#6d6d6d"),
        axis.text.x = element_text(size = 11),
        axis.line.x = element_line(color = "#7F7F7F"),
        axis.title.y = element_text(size = 11, hjust = 1 ,vjust = 2, color = "#6d6d6d"),
        axis.text.y = element_text(size = 11), 
        axis.line.y = element_line(color = "#7F7F7F"),
        axis.ticks = element_line(color="#a9a9a9") ,
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(0.5,2.5,0.5,0.5),"cm"))

ggsave("Figure 18.Final graph.png", height = 5, width = 8,units = "in",dpi = 300)

There will be a post dedicated to Titles, Subtitles, Captions, Axis Labels.

5. Other examples of line graphs.

5.1. Life expectation for North Americas Countries

library(gapminder)
df_gapminder <- gapminder
df_gapminder%>% 
  filter(country %in%  c("Canada","Mexico","United States")) %>% 
  ggplot() +
  geom_line(aes(x = factor(year),y = lifeExp, 
                color = country, group =  country), size = 1.75)+
  geom_text(data = df_gapminder %>% filter(country %in%  c("Canada","Mexico","United States"), year == 2007),
            aes(x = factor(year),y = lifeExp, color = country, label = country), 
            nudge_x = 0.2,
            hjust = 0,
            size = 4) +
  scale_y_continuous(expand =  c(0,0),limits = c(50,85),n.breaks = 8) +
  scale_colour_manual(values=c("Mexico" ="#483D8B", "United States" = "#006400","Canada" ="#0b1d78"))+
  labs(title = "Life expectancy of three North Americas Countries",
       caption = "Data source: gapminder.org",
       x = "Year",y = "Life expectancy") +
  coord_cartesian(clip = 'off') + 
  theme(plot.title = element_markdown(size=14, margin=margin(0,0,30,0),face="bold"),
        plot.subtitle = element_markdown(size=12, margin=margin(0,0,15,0)),
        plot.title.position = "plot",
        plot.caption = element_text(hjust = 0),
        plot.caption.position =  "plot",
        axis.title.x= element_text(size = 10, hjust = 0, vjust = 0, color = "#6d6d6d"),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "#7F7F7F"),
        axis.title.y = element_text(size = 10, hjust = 1 ,vjust = 2, color = "#6d6d6d"),
        axis.text.y = element_text(size = 10), 
        axis.line.y = element_line(color = "#7F7F7F"),
        axis.ticks = element_line(color="#a9a9a9") ,
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(0.5,2.75,0.5,0.5),"cm"))

ggsave("Figure 19.Life expectancy of three North Americas countries.png", height = 5, width = 8,units = "in",dpi = 300)

5.2. Indexed chart

The line chart can also be used for indexed chart.

data <- read_csv("gta_realestate.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   city = col_character(),
##   year = col_double(),
##   type = col_character(),
##   price = col_double()
## )
df_modified <- data%>% 
  filter(year >= 2015) %>% 
  group_by(city, type) %>% 
  mutate(ind = 100*price/ first(price))

df_modified 
## # A tibble: 54 x 5
## # Groups:   city, type [9]
##    city        year type            price   ind
##    <chr>      <dbl> <chr>           <dbl> <dbl>
##  1 Toronto     2015 detached home 1039638  100 
##  2 Toronto     2016 detached home 1286605  124.
##  3 Toronto     2017 detached home 1250235  120.
##  4 Toronto     2018 detached home 1145892  110.
##  5 Toronto     2019 detached home 1363357  131.
##  6 Toronto     2020 detached home 1475758  142.
##  7 Missisauga  2015 detached home  868380  100 
##  8 Missisauga  2016 detached home 1114177  128.
##  9 Missisauga  2017 detached home 1140965  131.
## 10 Missisauga  2018 detached home 1033209  119.
## # ... with 44 more rows
ggplot() +
  geom_line(data =df_modified %>% filter(type == "detached home") ,
            aes(x = year,
                y = ind, 
                color = city, group =  city), size = 1.75) +
  
  scale_x_continuous(breaks=seq(2011, 2020,1)) +
  scale_y_continuous(expand =  c(0,0),limits = c(90,190),n.breaks =8) +
  annotate("text", x = 2020, y = 142, label = "+142 %, Toronto", color = "#6495ED", hjust =-0.1) + 
  annotate("text", x = 2020, y = 180, label = "+181 %, Brampton", color = "#1F497D", hjust =-0.1) + 
  annotate("text", x = 2020, y = 162, label = "+163 %, Missisauga", color = "#808000", hjust =-0.1 ) +
  scale_colour_manual(values=c("Toronto" ="#6495ED", "Brampton" = "#1F497D","Missisauga" ="#808000")) +
 
  labs(title = "Indexed average prices for detached homes (Dec 2011-Dec 2020)",
       caption = "Data source: Toronto Regional Real Estate Board",
       subtitle = "Index, 2011 price = 100",
       x = "Year", y= "") +
  coord_cartesian(clip = 'off') + 
  theme(plot.title = element_markdown(size=14, margin=margin(0,0,30,0),face="bold"),
        plot.subtitle = element_markdown(size=12, margin=margin(0,0,15,0)),
        plot.title.position = "plot",
        plot.caption = element_text(hjust = 0),
        plot.caption.position =  "plot",
        axis.title.x= element_text(size = 10, hjust = 0, vjust = 0, color = "#6d6d6d"),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "#7F7F7F"),
        axis.title.y = element_text(size = 10, hjust = 1 ,vjust = 2, color = "#6d6d6d"),
        axis.text.y = element_text(size = 10), 
        axis.line.y = element_line(color = "#7F7F7F"),
        axis.ticks = element_line(color="#a9a9a9") ,
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(0.5,3.5,0.5,0.5),"cm"))

ggsave("Figure 20.Indexed average prices for detached homes.png", height = 5, width = 8,units = "in",dpi = 300)
ggplot() +
  geom_line(data =df_modified %>% filter(type == "semi-detached home") ,
            aes(x = year,
                y = ind, 
                color = city, group =  city), size = 1.75) +
  
  scale_x_continuous(breaks=seq(2011, 2020,1)) +
  scale_y_continuous(expand =  c(0,0),limits = c(90,190),n.breaks =8) +
  annotate("text", x = 2020, y = 156, label = "+156 %, Toronto", color = "#6495ED", hjust =-0.1) + 
  annotate("text", x = 2020, y = 178, label = "+178 %, Brampton", color = "#1F497D", hjust =-0.1) + 
  annotate("text", x = 2020, y = 162, label = "+160 %, Missisauga", color = "#808000", hjust =-0.1 ) +
  scale_colour_manual(values=c("Toronto" ="#6495ED", "Brampton" = "#1F497D","Missisauga" ="#808000")) +
 
  labs(title = "Indexed average prices for semi-detached homes (Dec 2011-Dec 2020)",
       caption = "Data source: Toronto Regional Real Estate Board",
       subtitle = "Index, 2011 price = 100",
       x = "Year", y= "") +
  coord_cartesian(clip = 'off') + 
  theme(plot.title = element_markdown(size=14, margin=margin(0,0,30,0),face="bold"),
        plot.subtitle = element_markdown(size=12, margin=margin(0,0,15,0)),
        plot.title.position = "plot",
        plot.caption = element_text(hjust = 0),
        plot.caption.position =  "plot",
        axis.title.x= element_text(size = 10, hjust = 0, vjust = 0, color = "#6d6d6d"),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "#7F7F7F"),
        axis.title.y = element_text(size = 10, hjust = 1 ,vjust = 2, color = "#6d6d6d"),
        axis.text.y = element_text(size = 10), 
        axis.line.y = element_line(color = "#7F7F7F"),
        axis.ticks = element_line(color="#a9a9a9") ,
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(0.5,3.5,0.5,0.5),"cm"))

ggsave("Figure 21.Indexed average prices for semi-detached homes.png", height = 5, width = 8,units = "in",dpi = 300)
df_modified 
## # A tibble: 54 x 5
## # Groups:   city, type [9]
##    city        year type            price   ind
##    <chr>      <dbl> <chr>           <dbl> <dbl>
##  1 Toronto     2015 detached home 1039638  100 
##  2 Toronto     2016 detached home 1286605  124.
##  3 Toronto     2017 detached home 1250235  120.
##  4 Toronto     2018 detached home 1145892  110.
##  5 Toronto     2019 detached home 1363357  131.
##  6 Toronto     2020 detached home 1475758  142.
##  7 Missisauga  2015 detached home  868380  100 
##  8 Missisauga  2016 detached home 1114177  128.
##  9 Missisauga  2017 detached home 1140965  131.
## 10 Missisauga  2018 detached home 1033209  119.
## # ... with 44 more rows
ggplot() +
  geom_line(data =df_modified %>% filter(type == "condo") ,
            aes(x = year,
                y = ind, 
                color = city, group =  city), size = 1.75) +
  
  scale_x_continuous(breaks=seq(2011, 2020,1)) +
  scale_y_continuous(expand =  c(0,0),limits = c(90,190),n.breaks =8) +
  annotate("text", x = 2020, y = 156, label = "+156 %, Toronto", color = "#6495ED", hjust =-0.1) + 
  annotate("text", x = 2020, y = 187, label = "+187 %, Brampton", color = "#1F497D", hjust =-0.1) + 
  annotate("text", x = 2020, y = 177, label = "+177 %, Missisauga", color = "#808000", hjust =-0.1 ) +
  scale_colour_manual(values=c("Toronto" ="#6495ED", "Brampton" = "#1F497D","Missisauga" ="#808000")) +
 
  labs(title = "Indexed condo (Dec 2011-Dec 2020)",
       caption = "Data source: Toronto Regional Real Estate Board",
       subtitle = "Index, 2011 price = 100",
       x = "Year", y= "") +
  coord_cartesian(clip = 'off') + 
  theme(plot.title = element_markdown(size=14, margin=margin(0,0,30,0),face="bold"),
        plot.subtitle = element_markdown(size=12, margin=margin(0,0,15,0)),
        plot.title.position = "plot",
        plot.caption = element_text(hjust = 0),
        plot.caption.position =  "plot",
        axis.title.x= element_text(size = 10, hjust = 0, vjust = 0, color = "#6d6d6d"),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "#7F7F7F"),
        axis.title.y = element_text(size = 10, hjust = 1 ,vjust = 2, color = "#6d6d6d"),
        axis.text.y = element_text(size = 10), 
        axis.line.y = element_line(color = "#7F7F7F"),
        axis.ticks = element_line(color="#a9a9a9") ,
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(0.5,3.5,0.5,0.5),"cm"))

ggsave("Figure 22.Indexed condo price.png", height = 5, width = 8,units = "in",dpi = 300)
theme_ind <-theme(plot.title = element_markdown(size=12, margin=margin(0,0,15,0),face="bold"),
        plot.subtitle = element_markdown(size=10, margin=margin(0,0,10,0)),
        plot.title.position = "plot",
        plot.caption = element_text(size=8,hjust = 0),
        plot.caption.position =  "plot",
        axis.title.x= element_text(size = 10, hjust = 0, vjust = 0, color = "#6d6d6d"),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "#7F7F7F"),
        axis.title.y = element_text(size = 10, hjust = 1 ,vjust = 2, color = "#6d6d6d"),
        axis.text.y = element_text(size = 10), 
        axis.line.y = element_line(color = "#7F7F7F"),
        axis.ticks = element_line(color="#a9a9a9") ,
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(0.5,2,0.5,0.5),"cm"))

p1 <- ggplot() +
  geom_line(data =df_modified %>% filter(type == "condo") ,
            aes(x = year,
                y = ind, 
                color = city, group =  city), size = 1.75) +
  
  scale_x_continuous(breaks=seq(2011, 2020,1)) +
  scale_y_continuous(expand =  c(0,0),limits = c(90,190),n.breaks =8) +
  annotate("text", x = 2020, y = 156, label = "+156 %, Toronto", color = "#6495ED", hjust =-0.1) + 
  annotate("text", x = 2020, y = 187, label = "+187 %, Brampton", color = "#1F497D", hjust =-0.1) + 
  annotate("text", x = 2020, y = 177, label = "+177 %, Missisauga", color = "#808000", hjust =-0.1 ) +
  scale_colour_manual(values=c("Toronto" ="#6495ED", "Brampton" = "#1F497D","Missisauga" ="#808000")) +
 
  labs(title = "Indexed average price sale for condos (Dec 2015-Dec 2020)",
       caption = "Data source: Toronto Regional Real Estate Board",
       subtitle = "Index, 2015 price = 100",
       x = "Year", y= "") +
  coord_cartesian(clip = 'off') + theme_ind

p2 <- ggplot() +
  geom_line(data =df_modified %>% filter(type == "semi-detached home") ,
            aes(x = year,
                y = ind, 
                color = city, group =  city), size = 1.75) +
  
  scale_x_continuous(breaks=seq(2011, 2020,1)) +
  scale_y_continuous(expand =  c(0,0),limits = c(90,190),n.breaks =8) +
  annotate("text", x = 2020, y = 156, label = "+156 %, Toronto", color = "#6495ED", hjust =-0.1) + 
  annotate("text", x = 2020, y = 178, label = "+178 %, Brampton", color = "#1F497D", hjust =-0.1) + 
  annotate("text", x = 2020, y = 162, label = "+160 %, Missisauga", color = "#808000", hjust =-0.1 ) +
  scale_colour_manual(values=c("Toronto" ="#6495ED", "Brampton" = "#1F497D","Missisauga" ="#808000")) +
 
  labs(title = "Indexed average price sale for semi-detached homes (Dec 2015-Dec 2020)",
       caption = "Data source: Toronto Regional Real Estate Board",
       subtitle = "Index, 2015 price = 100",
       x = "Year", y= "") +
  coord_cartesian(clip = 'off')+ theme_ind

p3 <- ggplot() +
  geom_line(data =df_modified %>% filter(type == "detached home") ,
            aes(x = year,
                y = ind, 
                color = city, group =  city), size = 1.75) +
  
  scale_x_continuous(breaks=seq(2011, 2020,1)) +
  scale_y_continuous(expand =  c(0,0),limits = c(90,190),n.breaks =8) +
  annotate("text", x = 2020, y = 142, label = "+142 %, Toronto", color = "#6495ED", hjust =-0.1) + 
  annotate("text", x = 2020, y = 180, label = "+181 %, Brampton", color = "#1F497D", hjust =-0.1) + 
  annotate("text", x = 2020, y = 162, label = "+163 %, Missisauga", color = "#808000", hjust =-0.1 ) +
  scale_colour_manual(values=c("Toronto" ="#6495ED", "Brampton" = "#1F497D","Missisauga" ="#808000")) +
 
  labs(title = "Indexed average price sale for detached homes (Dec 2015-Dec 2020)",
       caption = "Data source: Toronto Regional Real Estate Board",
       subtitle = "Index, 2015 price = 100",
       x = "Year", y= "") +
  coord_cartesian(clip = 'off')+ theme_ind

plot_grid(p1,p2,p3, ncol = 1, nrow = 3,rel_heights = c(1, 1,1))+ theme_ind

ggsave("Figure 23.Indexed average price sale.png", height = 12, width = 7.5,units = "in",dpi = 300)

5.3. Scaling effect

year <- c(1990:1999)
ABC <- c(1,2,3,4,5,6,5.3,9.2,9,10)
DEF <- c(10,20,30,40,50,60,53,92,90,100)
df_wide <- tibble(year, ABC, DEF)
df_wide
## # A tibble: 10 x 3
##     year   ABC   DEF
##    <int> <dbl> <dbl>
##  1  1990   1      10
##  2  1991   2      20
##  3  1992   3      30
##  4  1993   4      40
##  5  1994   5      50
##  6  1995   6      60
##  7  1996   5.3    53
##  8  1997   9.2    92
##  9  1998   9      90
## 10  1999  10     100
df_long <- df_wide %>% 
  pivot_longer(cols = c("ABC","DEF"), 
               names_to = "type", 
               values_to = "value")

head(df_long,10)
## # A tibble: 10 x 3
##     year type  value
##    <int> <chr> <dbl>
##  1  1990 ABC       1
##  2  1990 DEF      10
##  3  1991 ABC       2
##  4  1991 DEF      20
##  5  1992 ABC       3
##  6  1992 DEF      30
##  7  1993 ABC       4
##  8  1993 DEF      40
##  9  1994 ABC       5
## 10  1994 DEF      50
ggplot() +
  geom_line(data =df_long,aes(x = year,y = value,color = type, group = type), size = 1.75) +
  geom_point(data =df_long,aes(x = year,y = value, color = type), size =3)+
  scale_x_continuous(breaks=seq(1990, 1999,1)) +
  scale_y_continuous(expand =  c(0,0),limits = c(0,100),n.breaks =5) +
  scale_colour_manual(values=c("ABC"="#1F497D", "DEF" = "#490206")) +
  annotate("text", x = 1999.5, y = 10, label = "ABC", color = "#1F497D", hjust =-0.1) + 
  annotate("text", x = 1999.5, y = 100, label = "DEF", color = "#490206", hjust =-0.1) + 
  geom_text(data= df_long, aes(x = year, y = value, group =type,label= value,color = type),vjust = -1, hjust =0.75)+
  labs(title = "Stock Prices of two companies",
       caption = "",
       x = "Year", y= "") +
  coord_cartesian(clip = 'off')+ 
  theme_ind

Ref. Just Plain Data Analysis, Garry M. Klass, 2008, Rowman & Littlefield Inc.

ggsave("Figure 24.Linear scale.png", height = 5, width = 8,units = "in",dpi = 300)
ggplot() +
  geom_line(data =df_long,aes(x = year,y = value,color = type, group = type), size = 1.75) +
  geom_point(data =df_long,aes(x = year,y = value, color = type), size =3)+
  scale_x_continuous(breaks=seq(1990, 1999,1)) +
  scale_y_log10() +
  scale_colour_manual(values=c("ABC"="#1F497D", "DEF" = "#490206")) +
  annotate("text", x = 1999.5, y = 10, label = "ABC", color = "#1F497D", hjust =-0.1) + 
  annotate("text", x = 1999.5, y = 100, label = "DEF", color = "#490206", hjust =-0.1) + 

  geom_text(data= df_long, aes(x = year, y = value, group =type,label= value,color = type),vjust = -1, hjust =0.75)+
 
  labs(title = "Stock Prices of two companies",
       caption = "",
       x = "Year", y= "") +
  coord_cartesian(clip = 'off')+ 
  theme_ind

ggsave("Figure 25.Log scale.png", height = 5, width = 8,units = "in",dpi = 300)