Skip to content

Instantly share code, notes, and snippets.

@BobHarper1
Last active January 26, 2021 15:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BobHarper1/5db3f8a77bd120838aaba4804db71c11 to your computer and use it in GitHub Desktop.
Save BobHarper1/5db3f8a77bd120838aaba4804db71c11 to your computer and use it in GitHub Desktop.
Hourly heatmaps for visualisation of air quality data
## created after John Mackintosh's guide here http://johnmackintosh.com/2016-12-01-the-hourly-heatmap/. Thanks John!
library(ggplot2)
library(dplyr) # data wrangling
library(viridis) # colour blind friendly palettes, see https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html
library(lubridate) # for easy date manipulation
library(ggExtra)
library(tidyr)
library(readr)
airquality <- read_csv("~airquality.csv", ## data downloaded from http://www.airqualityni.co.uk/data/download-data 'measured data' (i.e. hourly observations)
col_types = cols(measure = col_number(),
time = col_character()))
df <- airquality
## convert the date and time character values (e.g. '20/12/2016' & '01:00') to a datetime object
## then obtain the year, month, day and hour as individual variables for each observation
df<- df %>% mutate(newdate = parse_date_time(paste(date,time), "%d/%m/%Y H:%M")) %>%
mutate(year = year(newdate),
month = month(newdate, label=TRUE),
day = day(newdate),
hour = hour(newdate))
#create plotting df
df <-df %>% select(day,hour,month,year,pollutant,measure,unit,site) %>%
filter(pollutant =='SO2' & !is.na(measure))
## ^^ change the pollutant to that which you want to measure (e.g. PM2.5, PM10, NO3, O3, SO2 etc.)
unit <- unique(df$unit)
pollutant <- unique(df$pollutant)
######## Plotting starts here#####################
p <-ggplot(df,aes(day,hour,fill=measure))+
geom_tile(color= "white") +
scale_fill_viridis(direction=-1,name=paste("Hourly",pollutant,unit))
p <-p + facet_grid(site ~ month)
## ^^ facets charts by individual site and month. If we were to include multi-year data, would need to facet by this also
p <-p + scale_y_continuous(trans = "reverse", breaks = unique(df$hour))
p <-p + scale_x_continuous(breaks =c(1,10,20,31))
p <-p + theme_minimal(base_size = 8)
p <-p + labs(title=paste("Hourly",pollutant,"concentration"), x="Day", y="Hour Commencing")
p <-p + theme(legend.position = "bottom")+
theme(plot.title=element_text(size = 14))+
theme(axis.text.y=element_text(size=6)) +
theme(strip.background = element_rect(colour="white"))+
theme(plot.title=element_text(hjust=0))+
theme(axis.ticks=element_blank())+
theme(axis.text=element_text(size=7))+
theme(legend.title=element_text(size=8))+
theme(legend.text=element_text(size=6))+
removeGrid()#ggExtra
p #draw chart
@Misterfluff
Copy link

Hi Bob
When I run your script, the console returns the following error:

^^ facets charts by individual site and month. If we were to include multi-year data, would need to facet by this also

p <-p + scale_y_continuous(trans = "reverse", breaks = unique(df$hour))
Error: object 'p' not found
I'm afraid I do not understand what is going on here. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment