tropical-expansion

This is an analysis of the expansion of the tropics over the last 100 years using a dataset from the 20th Century Reanalysis Project v2. A U-Wind (i.e. east-west) dataset was downloaded from this page:

http://www.esrl.noaa.gov/psd/data/gridded/data.20thC_ReanV2.monolevel.mm.html

Variable: U-wind
Statistic: Monthly Means
Level: 10M

The first plot is of the yearly mean u-wind speed by latitude.  A separate line was generated for each year for the 1911-2010 period.


The negative values are east winds and the positive are west.  As expected the easterly Trade Winds can be found in the tropics.  Also as expected the dividing line between the Trade Winds and the Westerlies can be found in the Horse Latitudes which are just poleward of 30 degrees.

Here's an animation of how the 100 year period evolves:



Next I calculated where the Trade Winds met the Westerlies in the Northern Hemisphere over the 100 year period:

Here is the summary of the regression:

Call:
lm(formula = zuwlat ~ yrs)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.35380 -0.36776  0.00127  0.44645  1.54601 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 2.992e+01  4.926e+00   6.075 2.36e-08 ***
yrs         7.612e-04  2.512e-03   0.303    0.763    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 0.7251 on 98 degrees of freedom
Multiple R-squared: 0.000936,   Adjusted R-squared: -0.009259 
F-statistic: 0.09181 on 1 and 98 DF,  p-value: 0.7625 

So the NH tropics are expanding at a rate of 0.007 degrees poleward per decade +/- 0.025 degrees.

For the period 1951-2010, here are the coefficient stats:

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 35.533229   9.789548   3.630 0.000601 ***
yrs         -0.002065   0.004943  -0.418 0.677619    

This shows an insignificant *equatorward* trend.

For the period 1979-1999, here are the coefficient stat:

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept) -5.50952   62.16770  -0.089    0.930
yrs          0.01850    0.03126   0.592    0.561

This shows a poleward trend.  I find this interesting because the 0.18 +/- 0.31 decadal rate looks compatible with the "mean meridional circulation (MMC)" rate found in the paper “Recent Northern Hemisphere tropical expansion primarily driven by black carbon and tropospheric ozone”, by Robert Allen et al, 2012.


FIGURE 3. ORIGINAL CAPTION: Figure 2 | Observed and modelled 1979–1999 Northern Hemisphere tropical expansion based on five metrics. a, Annual mean poleward displacement of each metric, as well as the combined ALL metric. … CMIP3 models are grouped into nine that included time-varying black carbon and ozone (red); three that included time-varying ozone only (green); and six that included neither time-varying black carbon nor ozone (blue). Boxes show the mean response within each group (centre line) and its 2s uncertainty. Observations are in black. In the case of one observational data set, trend uncertainty (whiskers) is estimated as the 95% confidence level according to a standard t-test.

Returning to my analysis, here is the plot for the Southern Hemisphere:
Call:
lm(formula = zuwlat ~ yrs)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.75228 -0.29743  0.04588  0.45548  1.59898 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -44.129566   4.796195  -9.201 6.56e-15 ***
yrs           0.005833   0.002446   2.385   0.0190 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 0.7061 on 98 degrees of freedom
Multiple R-squared: 0.05484,    Adjusted R-squared: 0.0452 
F-statistic: 5.686 on 1 and 98 DF,  p-value: 0.01902 

So there is a significant *equatorward* trend.  If a start year of 1950 was chosen then there would be a significant poleward trend.

By adding the NH and SH latitudes together, the width of the Meteorological Tropics can be calculated:
Call:
lm(formula = wzuwlat ~ yrs)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.7353 -0.7235 -0.0356  0.6097  2.7230 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 74.053719   7.453084   9.936   <2e-16 ***
yrs         -0.005072   0.003801  -1.334    0.185    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 1.097 on 98 degrees of freedom
Multiple R-squared: 0.01784,    Adjusted R-squared: 0.00782 
F-statistic:  1.78 on 1 and 98 DF,  p-value: 0.1852 

This shows a narrowing of the tropics.  Again, the sign of the trend is sensitive to the sample period.  Here are the coefficients for the period 1951-2010:

Coefficients:
             Estimate Std. Error t value Pr(>|t|)   
(Intercept) 48.311443  14.606205   3.308  0.00162 **
yrs          0.007882   0.007375   1.069  0.28960

So a decade expansion rate of 0.078 +/- 0.073 degrees.

Here's the source code:

library("RNetCDF") # needed to read nc file

# The following nc file was provided by the 20th Century Reanalysis Project v2
# Variable: U-wind (east-west measure)
# Statistic: Monthly Means
# Level: 10M
# See: http://www.esrl.noaa.gov/psd/data/gridded/data.20thC_ReanV2.monolevel.mm.html

ncfile <- "uwnd.10m.mon.mean.nc"

firstyr <- 1871 # first year on nc file
startyr <- 1911 # first year of analysis
endyr   <- 2010 # last  year of analysis

yrs     <- startyr:endyr
nyrs    <- length(yrs)

nc <- open.nc(ncfile)
 
long <- var.get.nc(nc,"lon")
lat  <- var.get.nc(nc,"lat")
time <- var.get.nc(nc,"time")

latx <- which(lat > -60 & lat < 60) # select latitudinal sample range
lats <- lat[latx]

slat <- min(latx)
clat <- length(latx)

uwnd <- NULL

for (i in startyr:endyr){

  stime <- (i - firstyr) * 12 + 1
  start <- c(NA,slat,stime)
  count <- c(NA,clat,12)
 
  # get sample for year, scale and offset found via print.nc(nc) function
 
  wsamp <- var.get.nc(nc,"uwnd",start,count,collapse=FALSE) * .01 + 27.66

  # average out longitudinal and time dimensions, i.e. mean by latitude and cbind to uwnd

  uwnd <- cbind(uwnd, apply(wsamp,2,mean))
}

dimnames(uwnd)[[1]] <- lats
dimnames(uwnd)[[2]] <- yrs

ymn <- floor(min(uwnd))
ymx <- ceiling(max(uwnd))


# save plot to a png file

windows()
#png("u-winds-yrly-mean-by-lat.png", bg="white", width=600, height=600)

y <- uwnd
matplot(lats, y, type = "l", col = rainbow(ncol(uwnd)), ylim=c(ymn,ymx),
        main=paste("Yearly Mean U-Winds ",startyr,"-",endyr,sep=""),
        ylab="U-Winds m/s",xlab="Latitude")
abline(h=seq(ymn,ymx,1.0),v=seq(min(lats),max(lats),10),lty="dotted",col="lightgrey")

#dev.off()

# Function which linearly interpolates the latitude at which the U-Winds are zero
# That is, where the easterly trades meet the westerlies
# A vector of mean U-Winds are passed in and associated latitudes are in zlats

eastmeetswest <- function(uw){

  htest <- lm(uw ~ zlats)$coeff[2] # used to test what hemisphere we are examining
  
  # determine two points adjacent to the zero U-Wind latitude
  
  if (htest > 0){              # NH if positive
    p2x <- max(which(uw > 0))
    p1x <- p2x + 1}
  else {                       # SH if negative
    p2x <- min(which(uw > 0))
    p1x <- p2x - 1}
      
  # calculate intercept using linear interpolation of the two adjacent points
      
  x1 <- uw[p1x]
  x2 <- uw[p2x]
  y1 <- zlats[p1x]
  y2 <- zlats[p2x]

  # calculate slope of line
  
  m <- (y2 - y1)/(x2 - x1)  

  # calculate intercept
  
  b <- m * -x1 + y1

  return(b)

}

#############
### Calculate zero U-Wind Latitudes in NH

zlatx <- which(lats > 20 & lats < 40) # Select sampled latitudes 
zlats <- lats[zlatx]
zuwnd <- uwnd[zlatx,]

# Calculate zero latitudes
nhzuwlat <- unlist(apply(zuwnd,2,eastmeetswest))

# Linear regression

zline <- lm(nhzuwlat ~ yrs)
zpred <- predict(zline)

windows()
#png("zero-u-wind-lats-NH.png", bg="white", width=600, height=600)

plot(yrs,nhzuwlat,type='l',
       main="Zero Yearly Mean U-Wind Latitudes - NH",
        ylab="Latitude",xlab="Year")

lines(yrs,zpred,type='l',lwd=2)

#dev.off()
 
summary(zline)

#############
### Calculate zero U-Wind Latitudes in SH

zlatx <- which(lats < -20 & lats > -40) # Select sampled latitudes 
zlats <- lats[zlatx]
zuwnd <- uwnd[zlatx,]

# Calculate zero latitudes
shzuwlat <- unlist(apply(zuwnd,2,eastmeetswest))

# Linear regression

zline <- lm(shzuwlat ~ yrs)
zpred <- predict(zline)

windows()
#png("zero-u-wind-lats-SH.png", bg="white", width=600, height=600)

plot(yrs,shzuwlat,type='l',
       main="Zero Yearly Mean U-Wind Latitudes - SH",
        ylab="Latitude",xlab="Year")

lines(yrs,zpred,type='l',lwd=2)

#dev.off()

summary(zline)

#############
### Calculate Width of Meteorological Tropics


wzuwlat <- nhzuwlat + abs(shzuwlat)

# Linear regression

zline <- lm(wzuwlat ~ yrs)
zpred <- predict(zline)

windows()
#png("zero-u-wind-lats-NH+SH.png", bg="white", width=600, height=600)

plot(yrs,wzuwlat,type='l',
       main="Meteorological Tropics Width in Degrees Latitude",
        ylab="Degrees Latitude",xlab="Year")

lines(yrs,zpred,type='l',lwd=2)

#dev.off()

summary(zline)

##################
# create animation of U-Winds
##################

library(animation) # needed to produce avi, requires ImageMagick software installation

##################
# makeplot function used by saveMovie animation function

makeplot <- function(){
 for(i in 1:nyrs)
 {
     y <- uwnd
     if(i<nyrs)
         y[,(i+1):nyrs] <- NA
     matplot(lats, y, type = "l", col = rainbow(ncol(uwnd)), ylim=c(ymn,ymx),
             main=paste("Yearly Mean U-Winds (",yrs[i],")",sep=""),
             ylab="U-Winds m/s",xlab="Latitude")
     yl<-y[,i]
     lines(lats,yl,lwd=2,col=1)
     abline(h=seq(ymn,ymx,1.0),v=seq(min(lats),max(lats),10),lty="dotted",col="lightgrey")
 }
}

# create animation avi

oopt = ani.options(interval = 0, nmax = nyrs)
saveMovie(makeplot(),interval = 0.2, width = 480, height = 480)
ani.options(oopt)



Comments