This blog is run by Jason Jon Benedict and Doug Beare to share insights and developments on open source software that can be used to analyze patterns and trends in in all types of data from the natural world. Jason currently works as a geospatial professional based in Malaysia. Doug lives in the United Kingdom and is currently Director of Globefish Consultancy Services which provides scientific advice to organisations that currently include the STECF [Scientific, Technical and Economic Committee for Fisheries, https://stecf.jrc.europe.eu/] and ICCAT, https://www.iccat.int/en/

Thursday, 1 May 2014

Penang rainfall: is 2014 now catching up?

Key points of post

  • January, February and March 2014 were unusually dry and hot (see post from 12 March 2014);
  • Rainfall in April 2014 has been substantial, and in terms of cumulative rainfall, 2014 is now catching up with other years.

In previous articles we discussed the very dry start to 2014, but how have things progressed since?

A repetitive theme of these articles is how important it is to examine data in different ways, from different ‘vantage’ points,using different styles of plot.


Cumulative rainfall  is plotted in the graph above for selected years for the first five months of the year for the last 10 years. [This means that the rainfall each day is added to the day before and so on]. 2012 and 2009 were both wet years overall up to the end of May; but note that 2012 also had an exceptionally dry January (purple line). 2010 was the driest year out of these 10 for the five month period.

Despite the low rainfall in January and February 2014, relatively high rainfall since the start of April (day 90) has propelled the cumulative total rapidly upwards. It follows that, by December, 2014 could end up anywhere in terms of total rainfall.

We will keep you updated.

The data used for the cumulative rainfall plot is again sourced from the Global Surface Summary of the Day (GSOD) product developed by the Federal Climate Complex at the National Climatic Data Centre (NCDC).

And the R code used to create the above plot is shown below

# Load required libraries 
library(plyr)
library(ggplot2)
library(lubridate)
library(date)
 
# Setting work directory
 
setwd("d:\\ClimData")
 
# Reading and reformatting GSOD raw data downloaded from NCDC
 
dat<-read.table("CDO2812586929956.txt",header=F,skip=1)
 
colnames(dat)<-c("stn","wban","yearmoda","temp","tempc","dewp","dewpc","slp","slpc","stp","stpc","visib","visibc","wdsp","wdspc","mxspd","gust","maxtemp","mintemp","prcp","sndp","frshtt")
 
dat$yearmoda <- strptime(dat$yearmoda,format="%Y%m%d")
 
dat$prcp <- as.character(dat$prcp)
dat$prcp1 <-as.numeric(substr(dat$prcp,1,4))
dat$prcpflag <- substr(dat$prcp,5,5)
 
# Convert precipitation from inches to mms
 
dat$rain  <- dat$prcp1*25.4
 
# Remove erronous values
 
dat$rain[dat$rain > 1000 ] <- NA
 
dat$year <- as.numeric(format(dat$yearmoda,"%Y"))
dat$month <- as.numeric(format(dat$yearmoda,"%m"))
dat$day <- as.numeric(format(dat$yearmoda,"%d"))
 
# Getting cumulative sum of rain/year
 
dat$date<-as.Date(dat$yearmoda)
 
 
# Subsetting required period
 
dat2 <- subset(dat, year >= 2005 & month <= 4 )
 
# Extracting required columns for transforming data
 
dat3 <- dat2[, c(25,29)]
 
# Replace na's with 0's for ddply function
 
dat3$rain[is.na(dat3$rain)] <- 0
 
dat3 <- ddply(dat3,.(year(date)),transform, cumRain = cumsum(rain))
 
dat4 <- ddply(dat3,.(date,year(date)),summarize, max = max(cumRain))
 
dat5 <- dat4[c(diff(as.numeric(substr(dat4$date, 9, 10))) < 0, TRUE), ]
 
dat5$year <- as.numeric(format(dat5$date,"%Y"))
dat5$month <- as.numeric(format(dat5$date,"%m"))
dat5$day <- as.numeric(format(dat5$date,"%d"))
 
# Calculate julian day for labeling
 
dat5$jday <- strptime(dat5$date, "%Y-%m-%d")$yday+1
 
 
# Plot cumulative rainfall
 
plot.title = 'Cumulative Rainfall by Year - January to May (2005-2014)'
plot.subtitle = 'Data source : Federal Climate Complex, Global Surface Summary Of Day Data Version 7'
 
cr<-  ggplot(dat3, aes(x = yday(date), y = cumRain, color = factor(year(date)))) +
      geom_line(size=0.5,linetype='solid') + geom_point(size=1.5) + theme_bw() +
      ggtitle(bquote(atop(.(plot.title), atop(italic(.(plot.subtitle)), "")))) + theme(plot.title = element_text(face = "bold",size = 16,colour="black")) +
      guides(color = guide_legend(title = "Year", title.position = "top")) +
      scale_x_continuous(breaks=c(0,30,60,90,120,150,180,210,240,270,300,330,360)) +
      scale_y_continuous(limits=c(0,800))+
      xlab("Julian Day") + ylab("Rainfall (mm)\n")+
      theme(panel.border = element_rect(colour = "black",fill=F,size=1),
      panel.grid.major = element_line(colour = "grey",size=0.25,linetype='longdash'),
      panel.grid.minor = element_blank(),
      panel.background = element_rect(fill = "ivory",colour = "black"),
      legend.position="right") 
 
cr <- cr + geom_text(data = subset(dat5, jday > 100 | year == 2014 & jday > 120 ), (aes(x = yday(date), y = max, label = year(date))),size=3,vjust=-0.2, hjust=-0.2)
 
cr 
 
ggsave(cr, file="Cumulative_RF_Penang.png", width=13, height=7,type = "cairo-png")
Created by Pretty R at inside-R.org

Monday, 21 April 2014

Penang: hot nights driving long-term change

 Key points of post
  • It is getting hotter in Penang

  • This change is 'driven' by night-time temperatures


In our previous blog posts (20 and 25 February 2014), we plotted monthly temperature data for Penang International Airport which showed how average air temperatures have increased steadily since the mid-1970s.

Time-series analysis, however, can be a tricky business and interpretations can only be made at the level of temporal aggregation (monthly, quarterly, weekly) initially selected. It is difficult to decide which level of aggregation is ‘best’. A general rule would be that you would want to analyze your time-series at the finest resolution possible. When you do aggregate your series in ‘chunks of time’, you need to make sure that any source of bias or confounding is not being masked or disguised by the aggregation step itself. You might, for example, have a series with missing Januaries at the start and missing Augusts at the end. Clearly it would be possible to plot and analyze the data at a quarterly resolution, but any long-term trends observed would be biased.

 
Here we have plotted the same temperature data that we have seen before, but this time at hourly resolution (for selected years). Plotting the data in this way shows the pronounced difference between night-time and day-time temperatures. Not surprisingly it’s generally a lot warmer during the day (red and orange bands) than it is at night (blue bands). You might also notice the spots and bands in grey at certain sections of the plot which are actually gaps in the hourly temperature data records.

What’s interesting, though, is that it is not the day-time temperatures that have increased over time, but the night-time temperatures. [Note the much bluer banding at night in 1979, 1985, and 1989 than is seen in more recent years (2010 & 2013)].

This demonstrates that the long-term trends in air temperature in Penang that we’ve seen before are not due to warmer day-time temperatures, which have been rather stable, but to warmer nights. It’s always tempting to attribute long-term changes in temperatures to climate change due to global warming. This warming trend, however, could just as easily be an ‘urban heat island’ effect. Penang’s economic development has been rapid over the last four decades and the ‘built environment’ is much larger than it used to be. All this extra concrete might be storing up heat during the day to release at night.

Whatever the cause, for ordinary Penangites it is still hotter, and the average temperatures still higher. As usual the data for this analysis are available freely online and the code to produce the plot is outlined below.

The raw data that was used to produce the hourly temperature 'strip' plot was acquired from the Integrated Surface Database (ISD) maintained by the National Climatic Data Centre at NOAA (http://www.ncdc.noaa.gov/oa/climate/isd/). According to the website, the database comprises over 20,000 stations worldwide, with some having data as far back as 1901, though the data show a substantial increase in volume in the 1940's and again in the early 1970's. Currently there are over 11,000 stations "active" and updated daily. This data is again available to be requested and downloaded without charge from the website.

The above hourly temperature plot was produced with one of the functions as part of an R package called 'Metvurst' (METeorological Visualisation Utilities Using R for Science and Teaching) developed by Tim Salabim and you can find more information and instructions on how to install and use it at the following link - http://metvurst.wordpress.com

The package can also be downloaded via the GitHub page below

http://tim-salabim.github.io/metvurst/


The detailed R code used to produce the plot is as below
# Setting work directory
 
setwd("d:\\ClimData")
 
list.files()
 
# Reading and reformatting raw daily data downloaded from ISD NCDC
 
dat<-read.table("2110827004508dat.txt",header=TRUE,fill=TRUE,na.strings=c("*","**","***","****","*****","******","0.00T*****"))
 
colnames(dat)<-tolower(colnames(dat))
 
# Convert hourly data from UTC to local time zone
 
Sys.setenv(TZ = "UTC")
dat$dates <- as.POSIXct(strptime(dat$yr..modahrmn,format="%Y%m%d%H%M"))  + 8 * 60 * 60
  
# Convert temperatures in Degree Fahrenheit to Degree Celcius
  
dat$tempc <- (dat$temp-32) * (5/9)
 
dat$tempc[dat$tempc<=10] <- NA
dat$tempc[dat$tempc>=40] <- NA 
 
# Extract years and month 
 
dat$year <- as.numeric(format(dat$dates,"%Y"))
 
dat$month <- as.numeric(format(dat$dates,"%m"))
  
# Load metvurst library
 
library(metvurst)
 
 
# Subset data for selected years
 
datsub <- subset(dat,year == 1979 | year == 1985 | year == 1989  | year == 1999 | year == 2001 | year == 2005 | year == 2010 | year == 2013 )
 
png(filename = "Penang_Daily_Temps_Cairo.png",height=8,width=12,
    bg = "white",units='in', res = 600, family = "", restoreConsole = TRUE,
    type = "cairo-png")
 
# Plot hourly air temperatures using the 'strip' function
 
plot.air.temp <- strip(x = datsub$tempc,
                       date = datsub$dates,
                       cond = datsub$year,
                       arrange = "long",
                       colour = colorRampPalette(rev(brewer.pal(11, "Spectral"))),
                       main = "Daily Air Temperature in Penang (Bayan Station) on Selected Years\n\nTemperature [°C]",
                       sub="Data source: Integrated Surface Database (ISD) - National Climatic Data Centre (NCDC)",font.sub=2)
 
print(plot.air.temp)
 
 
dev.off()
Created by Pretty R at inside-R.org

Wednesday, 12 March 2014

2014 has seen drought and forest fires on Penang Island

Key point of post
  •  February 2014 was the driest since 1990 and in the top 5 warmest

     

 2014 and ‘The Pearl of the Orient’ is looking parched. The grass is brown, the epiphytes that normally festoon the ‘rain’ trees in the Youth Park are wilted, and we’ve even had forest fires in the hills behind the main conurbations (see photos below). Last week aircraft were collecting seawater off Gurney Drive to douse the flames and, according to our friends in Penang, the current dry spell is unprecedented.









Further down south on the steep slopes of Bukit Jambul, there are recurring fires at various patches along the hills. The photo below was taken a few nights ago showing the fires on the hills just behind the Bukit Jambul High School and it has yet to cease entirely since this post was created.

 

As we’ve seen in previous post, while there is some ‘predictable’ seasonality in rainfall on Penang, it is also rather erratic or variable. We’ve plotted daily total rainfall at Penang Airport, below, for 7 selected years, and the first 2 months of 2014. These years give an illustration of some typical patterns. Generally speaking December, January and February are indeed quite dry but this is not always true. January 2000 and February 2005 were, for example, quite wet; early February 2005 seeing greater than 50mms rain in one day.



So what about 2014? There was a bit of rain in mid-January (at least at the airport) but none fell at all in February. Total February rainfall (blue line) since 1990 is plotted below, together with average daily air temperatures for February (red line). February 2014 was the driest for nearly 25 years but not by that much. Februaries 1995 and 2001 were also very dry. [Data for further back in time were available but incomplete records and lines of zeros made us suspect their veracity.]



Perhaps then higher temperatures than usual have exacerbated the low rainfall situation and helped stoke the forest fires? Previously we demonstrated that temperatures have been rising in Penang over the last 20 or so years and the hot period of the year now lasts longer than in the past. February 2014 was pretty hot at around 28.5°C, but nothing like as sweltering as 2010 when a mean temperature of around 29°C was recorded, together with also quite low rainfall.

So what of the connection between temperature and rainfall? The average February temperatures and rainfall 1990-2014 are plotted against each other below. There is obviously a negative relationship between the two (the correlation coefficient = -0.4). Wetter Februaries tend to be cooler and vice-versa.

 


February 2014 has been the driest since 1990 but not the hottest (1998, 2002, 2005, 2010 were all warmer). In summary the relationship between rainfall, temperature, and the triggers for forest fires are complex. Other factors that we have not examined such as humidity and wind speed may also have contributed.

Nevertheless we have shown that February 2014 has been the driest since 1990 on Penang Island and is in the Top 5 warmest years.

As usual, we include the R code we have used to produce the plots in this post. The raw data for these plots however was downloaded from the Global Surface Summary of the Day (GSOD) which is a product developed by the National Climatic Data Centre (NCDC) based in the US. The input data used in building these daily summaries are the Integrated Surface Data (ISD), which includes global data obtained from the USAF Climatology Center, located in the Federal Climate Complex with NCDC. The latest daily summary data are normally available 1-2 days after the date-time of the observations used in the daily summaries.

The datasets can be downloaded from NCDC via a normal web interface at the link below
http://www7.ncdc.noaa.gov/CDO/cdoselect.cmd?datasetabbv=GSOD

or through their FTP site at the following link
# Setting work directory
 
setwd("d:\\ClimData")
 
list.files()
 
# Reading and reformatting raw data downloaded from NCDC
 
dat<-read.table("CDO2812586929956.txt",header=F,skip=1)
 
colnames(dat)<-c("stn","wban","yearmoda","temp","tempc","dewp","dewpc","slp","slpc","stp","stpc","visib","visibc","wdsp","wdspc","mxspd","gust","maxtemp","mintemp","prcp","sndp","frshtt")
 
dat$yearmoda <- strptime(dat$yearmoda,format="%Y%m%d")
 
min.date <- min(dat$yearmoda)
max.date <- max(dat$yearmoda)
 
dat$prcp <- as.character(dat$prcp)
dat$prcp1<- as.numeric(substr(dat$prcp,1,4))
dat$prcpflag <- substr(dat$prcp,5,5)
 
dat$rain  <- dat$prcp1*25.4
dat$tempdc <- (dat$temp-32) * (5/9)
 
dat$rain[dat$rain > 1000 ] <- NA
 
dat$year <- as.numeric(format(dat$yearmoda,"%Y"))
dat$month <- as.numeric(format(dat$yearmoda,"%m"))
dat$day <- as.numeric(format(dat$yearmoda,"%d"))
 
# Plotting precipitation for various years in Penang from daily precipitation data
 
library(ggplot2)
library(scales)
 
dat$date<-as.Date(dat$yearmoda)
 
datsub <- subset(dat, year == 1990 | year == 1995 | year == 2000 | year == 2005 | year == 2010 | year == 2012 | year ==2013 | year == 2014)
 
dat1 <- transform(datsub, date = as.Date(paste(2000, month, day, sep="/")))
 
boxplot.title = 'Precipitation in Penang'
boxplot.subtitle = 'Data source : Federal Climate Complex, Global Surface Summary Of Day Data Version 7'
 
g <- ggplot(dat1, aes(date, rain)) +
  geom_line(col="blue", size=0.65) + 
  facet_wrap( ~ year, ncol = 2) +
  xlab("") + ylab("Precipitation (mms)") +
  scale_x_date(label = date_format("%b"), breaks = seq(min(dat1$date), max(dat1$date), "month")) +
  scale_y_continuous(limits = c(0,150)) +
  ggtitle(bquote(atop(.(boxplot.title), atop(italic(.(boxplot.subtitle)), "")))) + theme(plot.title = element_text(face = "bold",size = 16,colour="black")) +
  theme(legend.position = "none") + theme_bw()
g
 
ggsave(g, file="Penang_GSOD_Prcp_Plots.png", width=10, height=7)
 
# Plotting Average monthly temperature and total precipitation
 
avgtemp <- aggregate(tempdc ~ year + month, data = dat, FUN = mean)
totrain <- aggregate(rain ~ year + month, data = dat, FUN = sum)
 
avgtempfeb <- subset(avgtemp, month == 2 & year >= 1990)
totrainfeb <- subset(totrain, month == 2 & year >= 1990)
 
par(mar=c(5,4,4,5)+.1)
plot(avgtempfeb$year,avgtempfeb$tempdc,type="b",col="red",lwd=3,xlab="",ylab="")
par(new=TRUE)
plot(avgtempfeb$year,totrainfeb$rain,,type="b",col="blue",lwd=3,xaxt="n",yaxt="n",xlab="Year",ylab="Temperature (Degree C)",
     main = "Average temperature and total precipitation \n for the month of February in Penang for years 1990-2014")
axis(4)
mtext("Precipitation (mms)",side=4,line=3)
abline(v=1949:2014,lty=3,col='grey70')
legend("topleft",col=c("red","blue"),lwd=3,legend=c("Temperature","Precipitation"))
 
dev.off()
 
# Plot correlation between average temperature and total precipitation
 
png(filename = "Penang_TempPrcp_Correlation_Years_1990-2014.png",height=5,width=10,
    bg = "white",units='in', res = 300, family = "", restoreConsole = TRUE,
    type = "windows")
 
reg <- lm(totrainfeb$rain~avgtempfeb$tempdc)
plot(avgtempfeb$tempdc,totrainfeb$rain,type='n',xlab="Temperature (Degree C)",ylab="Precipitation (mms)",
     main = "Correlation between average temperature and total precipitation \n for the month of February in Penang for years 1990-2014")
 
abline(v=c(27.5,28,28.5,29,29.5,30),lty=3,col='grey70')
abline(h=c(0,50,100,150,200.250,300),lty=3,col='grey70')
text(avgtempfeb$tempdc,totrainfeb$rain,as.character(totrainfeb$year),cex=1.2,col="red")
box(lty = "solid", col = 'black',lwd=3)
 
# Correlation value between total precipitation and temperatures
 
cor(totrainfeb$rain,avgtempfeb$tempdc)
 
dev.off()
Created by Pretty R at inside-R.org