Create Plots in a Loop & Save Using ggplot in R
4 min readJun 4, 2019
What you will learn in this post?
- Setting working directory
- Reading tab separated file
- Using pipes i.e. %>%
- Creating plots in a loop using ggplot
i) Create bar plot
ii) Rotate x axis text by 90 degrees
iii) Give title to the plot
iv) Give labels to x and y axes
v) Change title font size, position and type (make them bold)
vi) Change x and y axes font size and type (make them bold) - Saving plots in a list
- Displaying plot on screen
- Saving plots to disk
i) Give height and width to plot in cm
ii) Set dpi (dots per inch) for plot
Without testing limits to your patience, here is the complete code we will deconstruct in the post.
library("data.table")
library("dplyr")
library("ggplot2")
setwd("~/tutorials/R")
file_name <- "ggplot_loop_data.tsv"
dat <- fread(file_name, sep="\t")
cities = unique(dat$city)
city_plots = list()
for(city_ in cities) {
city_plots[[city_]] = ggplot(dat %>% filter(city == city_), aes(x=zone, y=`multistorey buildings`)) + geom_bar(stat="identity") + theme(axis.text.x = element_text(angle = 90)) + ggtitle(city_) + ylab("No. of multistorey buildings") + xlab("Area") + theme(plot.title = element_text(size = 32, face = "bold", hjust=0.5), axis.title.x = element_text(size = 18, face = "bold"), axis.title.y = element_text(size = 18, face = "bold"))
print(city_plots[[city_]])
ggsave(city_plots[[city_]], file=paste0("plot_", city_,".png"), width = 44.45, height = 27.78, units = "cm", dpi=300)
}
Explanation
For understanding I find it better to have inline comments to the code — so here it is …..
# For reading data
library("data.table")# For Data Manipulation (specially %>% operator in the code)
library("dplyr")# For Plotting
library("ggplot2")# You can set by giving absolute path or relative path
setwd("~/tutorials/R")# Set file name to be read - note this is a tab separated file
file_name <- "ggplot_loop_data.tsv"# Reading tab separated file by setting separator parameter \t signifies tab separation
dat <- fread(file_name, sep="\t")# Getting unique city names to loop over. This is used to create a different plot for every city
cities = unique(dat$city)# Create an empty list to save plots created. Lists in R are very versatile. They can pretty much store any type of data in them.
city_plots = list()# looping over unique cities
for(city_ in cities) {
# dat %>% filter(city == city_) takes dat as input and sends it to filter function which filters it based on condition that city column should be equal to loop variable city_ # `multistorey buildings` backticks are used since there is a space in column name. You also use backticks if there are special characters in the name. # theme(axis.text.x = element_text(angle = 90)) rotates x axis text by 90 degrees in counter clockwise direction - the way we understand quadrants in math # ggtitle(city_) sets title dynamically based on current looping variable - for single plot this can be a string # xlab() and ylab() functions are setting axes labels # theme(plot.title = element_text(size = 32, face = "bold", hjust=0.5), axis.title.x = element_text(size = 18, face = "bold"), axis.title.y = element_text(size = 18, face = "bold")) is doing 3 things at once - first manipulating plot title by changing font size, making them bold and adjusting horizontally to place them at center of plot. second manipulating x axis text and third manipulating y axis text.# city_plots[[city_]] = ggplot(...) the plots created are ultimately saved in the list city_plots. Each plot is saved with the key corresponding to the looping variable - city_ city_plots[[city_]] = ggplot(dat %>% filter(city == city_), aes(x=zone, y=`multistorey buildings`)) + geom_bar(stat="identity") + theme(axis.text.x = element_text(angle = 90)) + ggtitle(city_) + ylab("No. of multistorey buildings") + xlab("Area") + theme(plot.title = element_text(size = 32, face = "bold", hjust=0.5), axis.title.x = element_text(size = 18, face = "bold"), axis.title.y = element_text(size = 18, face = "bold")) # print the plots created to screen
print(city_plots[[city_]]) # save the plots to disk. file parameter is used to give plot file name - it can be a complete path of the file name. width and height give dimensions to the file in units = "cm". dpi is dots per inch for the quality of plot ggsave(city_plots[[city_]], file=paste0("plot_", city_,".png"), width = 44.45, height = 27.78, units = "cm", dpi=300)
}
Hey its all well and good but how does the data we are plotting even looks like?? Okay okay.. here it is ….
Download the data from my github here ggplot_loop_data
And how to the plots look like?
We can definitely beautify them, eh?
PS: The data is hypothetical.