Objective

How to create line charts and customise them in ggplot. youtube video link with explanations for these examples https://youtu.be/y96uJAlTwNY

We will be using the following libraries for our charting needs.

library(ggplot2) # libary for charting
## Warning: package 'ggplot2' was built under R version 4.1.3
library(ggrepel) # Helps in the placement of the labels etc

library(ggthemes) #ggthemes gives us access to some additional themes and features
# Basic Line plot in ggplot and cutomisation

# We will use the built in datasets in R in this example.
#datasets::mtcars
# view the data frame to see the structure
head(mtcars)
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
# Notice that car names are store as the RowNames
# we can access them by using
# row.names(mtcars)
# Ready for plotting
# You would get an error and the chart will be empty as the line chart needs the group.

pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg))
pl <- pl + labs(title ="This chart does not produce any lines")
pl <- pl + labs(subtitle ="We did not define the group")

pl
## geom_path: Each group consists of only one observation. Do you need to adjust
## the group aesthetic?

# this can be fixed by giving group = 1 in the geom_line
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg),group =1)
pl <- pl + labs(title ="This chart produces the line chart properly")
pl <- pl + labs(subtitle ="We defined a group by giving group = 1 in geom_line")

pl

# Now make some adjustments to make the chart presentable

# use a inbuilt theme
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg),group =1)
pl <- pl + theme_bw()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl

Apply the theme first

Apply the theme first and then make any adjustments eg. changing the angle of the text and other such customisations. You would see and example below which will demonstrate why you need to apply the theme first and then fine tune any customisations after that.

# You would notice that we have given a statement to plot the x axis labels at 90 degrees, but the position of the statement matters.
# We applied the theme_classic in the last line therefore the previous statement to turn the text 90 degrees was overridden by the customisations applied by the theme_classic.

# use a inbuilt theme
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg),group =1)
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl + theme_classic()
pl <- pl + labs(title ="We customised the x axis text to be rotated by 90 degrees")
pl <- pl + labs(subtitle ="But it did not rotate the text, as we applied the theme afterwards")

pl

pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg),group =1)
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl + labs(title ="We customised the x axis text to be rotated by 90 degrees")
pl <- pl + labs(subtitle ="We applied the theme first and then applied any customisations after that. This is the correct way") 
pl

# Now change the colour of the line

pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg),group =1, color = "red")
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl

# adjust the y axis
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg ),group =1, colour = "red")
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl

# Set the titles
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg ),group =1, colour = "red")
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl + labs(title ="This is the title of your plot")
pl <- pl + labs(subtitle ="This is the subtitle")
pl <- pl + labs(caption ="what if your caption is really long and you would like to split it")
pl <- pl  + labs(x ="Cars", y = "Miles per gallon")
pl

# What if you want to see the values of the points as well
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg ),group =1, colour = "red")
pl <- pl + geom_text(aes(y = mpg, label = mpg ), colour = "blue")
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl + labs(title ="This is the title of your plot")
pl <- pl + labs(subtitle ="This is the subtitle")
pl <- pl + labs(caption ="what if your caption is really long and you would like to split it")
pl <- pl  + labs(x ="Cars", y = "Miles per gallon")
pl

# How to adjust the text values of the points
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg ),group =1, colour = "red")
pl <- pl + geom_text_repel(aes(y = mpg, label = mpg ), colour = "blue", vjust = -0.5, size = 3)
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl + labs(title ="This is the title of your plot")
pl <- pl + labs(subtitle ="This is the subtitle")
pl <- pl + labs(caption ="what if your caption is really long and you would like to split it")
pl <- pl  + labs(x ="Cars", y = "Miles per gallon")
pl

# How to adjust the text values of the points
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg ),group =1, colour = "red")
pl <- pl + geom_text_repel(aes(y = mpg, label = mpg ), colour = "blue", vjust = -0.5, size = 3)
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl + labs(title ="This is the title of your plot")
pl <- pl + labs(subtitle ="This is the subtitle")
pl <- pl + labs(caption ="what if your caption is really long and you would like to split it")
pl <- pl  + labs(x ="Cars", y = "Miles per gallon")
pl

# How to adjust some of the aspects of the theme
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg ),group =1, colour = "red")
pl <- pl + geom_text_repel(aes(y = mpg, label = mpg ), colour = "blue", vjust = -0.5, size = 3)
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl + labs(title ="This is the title of your plot")
pl <- pl + labs(subtitle ="This is the subtitle")
pl <- pl + labs(caption ="what if your caption is really long and you would like to split it")
pl <- pl  + labs(x ="Cars", y = "Miles per gallon")
pl

# How to put annotations in the chart
pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg ),group =1, colour = "red", linetype = "dashed") + geom_point(aes(y = mpg ))
pl <- pl + geom_text_repel(aes(y = mpg, label = mpg ), colour = "blue", vjust = -0.5, size = 3)

pl <- pl + annotate("rect", xmin =  7,  ymin= 28, xmax = 11, ymax= 35, fill = "red", alpha = 0.1)

pl <- pl + annotate("text", x = 11, y = 32, label ="High",  color= "purple")

pl <- pl + annotate("segment", x = 13,  y = 32, xend = 28, yend = 34, colour = "green")
pl <- pl +  annotate("pointrange", x = 9, y = 32.4, ymin = 35, ymax = 1, colour = "green")
pl <- pl +  annotate("pointrange", x = 29, y = 33.9, ymin = 35, ymax = 1, colour = "green")

pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl + labs(title ="This is the title of your plot")
pl <- pl + labs(subtitle ="This is the subtitle")
pl <- pl + labs(caption ="what if your caption is really long\n and you would like to split it")
pl <- pl  + labs(x ="Cars", y = "Miles per gallon")
#pl <- pl + gganimate::animate()
pl

pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg, colour = "mpg" ) , group =1  )
pl <- pl + geom_line(aes(y = cyl, colour = "cyl" ) , group =1)
pl <- pl + labs(x="", y="")
pl <-  pl+ labs(colour = "MPG and CYL")
pl <- pl + theme(legend.position = "top")
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl

pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg) , group = 1  )
pl <- pl + geom_point(aes(y = mpg))
pl <- pl + geom_text_repel(aes(y = mpg, label = mpg ), colour = "blue")
pl <- pl + annotate("rect", xmin =  7,  ymin= 28, xmax = 11, ymax= 35, fill = "red", alpha = 0.1)
pl <- pl + annotate("segment", x = 13,  y = 32, xend = 28, yend = 34, colour = "green")
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =0 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl + labs(title ="This is the title of your plot")
pl <- pl + labs(subtitle ="This is the subtitle")
pl <- pl + labs(caption ="what if your caption is really long\n and you would like to split it")
pl <- pl  + labs(x ="Cars", y = "Miles per gallon")
pl

# More annotations and styling


pl <- ggplot(data = mtcars, aes(x = row.names(mtcars)) )
pl <- pl + geom_line(aes(y = mpg ),group =1, colour = "red", linetype = "dotted", size = 1.5) 
pl <- pl + geom_point(aes(y = mpg, color = "red" , size = 1))
pl <- pl + geom_text_repel(aes(y = mpg, label = mpg ), colour = "blue", fontface = "bold", vjust = -0.5, size = 3,nudge_x = 1,point.padding = 1)

pl <- pl + annotate("rect", xmin =  7,  ymin= 28, xmax = 11, ymax= 35, fill = "orange", alpha = 0.3)
pl <- pl + annotate("rect", xmin =  27,  ymin= 28, xmax = 31, ymax= 38, fill = "orange", alpha = 0.3)

pl <- pl + annotate("text", x = 11, y = 32, fontface = "bold" ,label ="Highest value",  color= "purple")
pl <- pl + annotate("text", x = 29, y = 36, fontface = "bold" ,label ="Highest value",  color= "purple")

pl <- pl + annotate("segment", x = 10,  y = 32, xend = 28, yend = 34, colour = "red")
pl <- pl +  annotate("pointrange", x = 9, y = 32.4, ymin = 35, ymax = 1, colour = "grey")
pl <- pl +  annotate("pointrange", x = 29, y = 33.9, ymin = 35, ymax = 1, colour = "grey")

pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl <- pl + labs(title ="This is the title of your plot")
pl <- pl + labs(subtitle ="This is the subtitle")
pl <- pl + labs(caption ="what if your caption is really long\n and you would like to split it")
pl <- pl  + labs(x ="Cars", y = "Miles per gallon")
pl <- pl +  theme(legend.position = "none")
#pl <- pl + gganimate::animate()
pl

Multiple line on the same chart

So far we have not touched on how to plot more than one lines in the plot head(mtcars)

You can keep on add multiple geom_line statements by changing the Y axis as we have done in the above charts.

But there is a better way to plot multiple line That option is to use a long dataset (using melt from the reshape2 package)

library(reshape2)
mtcars$carname <- rownames(mtcars)
mtcars.melt <- reshape2::melt(mtcars, id = 'carname')
# You can keep on add multiple geom_line statements by changing the Y axis
# But there is a better way to plot multiple line
# That option is to use a long dataset (using melt)
# we will cover that in another video


pl <- ggplot(data = mtcars.melt, aes(x = carname, y = value, group = variable, colour = variable) )
pl <- pl + geom_line()
pl <- pl + labs(x="", y="")
pl <-  pl+ labs(colour = "MPG and CYL")
pl <- pl + theme(legend.position = "top")
pl <- pl + ggthemes::theme_economist_white()
pl <- pl  + theme(axis.text.x = element_text(angle = 90,hjust =1 ))
pl <- pl  + theme(axis.text.y = element_text(angle = 45, vjust = 1 ))
pl

Youtube video link https://youtu.be/y96uJAlTwNY