Correlation Plot (-1 to 0 to +1) on rworldmap

30 Views Asked by At

In my analysis, each country has its own correlation coefficient that I would like to plot into a worldmap. The correlation coefficient ranges from -1 (should be solid red) to +1 (should be solid blue), with 0 (should be white), and countries with intermediate correlation (e.g., 0.5) should be half white and half blue).

is catMethod and colourPalette set up for such a plot already?

1

There are 1 best solutions below

0
ivo Welch On

Probably buggy, but it does the job for me. First, I define a function that gives me a palette in the form that rworldmap agrees with me.

mkrwg <- function( plotvar, length.out= 100, col.neg= "red", col.zero= gray(0.9), col.pos= "blue" ) {
    rl <- abs(min(plotvar))/(max(plotvar) - min(plotvar))
    rr <- abs(max(plotvar))/(max(plotvar) - min(plotvar))
    rw <- head(colorRampPalette(c(col.neg, grey(0.9)))( rl * (length.out+1) ), -1)  ## remove one duplicate to merge
    wg <- colorRampPalette(c(gray(0.9), col.pos))( rr * (length.out+1) )
    c(rw,wg)
}

## test out color range
plotvar <- c(-0.1,0.1,seq( -20, 5, 1 ))  ## more range on the left
rwg <- mkrwg( plotvar )

o <- as.data.frame(do.call("rbind", lapply(  1:length(plotvar), function(wi) {
    ## cnvx is a little big buggy here, because -0.1 should be E6E6E6 rather than E6E3E3
    ## but this is just a test function
    cnvx <- function(x) (x - min(plotvar))/(max(plotvar)-min(plotvar))
    mci <- as.integer(cnvx( plotvar[wi] )*(length( rwg )-1)) + 1
    data.frame(obs=wi, val=plotvar[wi], calcindex=mci, coli=rwg[mci])
})))
    
print(o)
plot( o$val, (1:length(o$val)) %% 2, col=o$coli, cex=5, pch=16 ) ## zero value in gray

This produces

show off palette

OK, we match the zero value to our very light gray. Add the following now:

################################################################
## now integrate into rworldmap
################################################################

dev.new()  ## draw another figure now

plot.world <- function( ccode3, plotvar ) {
    dcs <- data.frame( ccode3, plotvar )

    sPDF <- joinCountryData2Map( dcs, joinCode = "ISO3", nameJoinColumn = "ccode3")
    sPDF <- sPDF[-which(getMap()$ADMIN=="Antarctica"),]

    rwgp <- mkrwg( plotvar )

#better:    par(mar= c(0,0,8,0), mai= c(0.3,0,0,0))
    mapCountryData( sPDF,
                   mapTitle="",
                   colourPalette=rwgp,
                   nameColumnToPlot= "plotvar",
                   numCats=max(10,length(plotvar)),
                   catMethod= "pretty",
                   #addLegend=F,
                   oceanCol='lightblue', borderCol="black", missingCountryCol="black" )
    iaw$hline( 0, lwd=0.5 )
    iaw$hline( c(-23.5, 23.5, 66.6), lwd=0.5, lty=3 )
}

library("rworldmap")

plot.world(c("USA", "MEX", "BRA", "RUS", "SDN", "CHN", "NZL", "AUS"),
           c(-4,    -3,    -3,    -2,    -1,     0,    0.5,    1) )

this produces

world map

China is the zero in this example.

Buglets:

  • Australia here has a smaller absolute coefficient (1) than the USA (4), but it gets the full "blue" treatment. The function could be improved to allow for a more symmetric treatment, too.

  • the color ramp is visually too similar for my taste on the extreme red end. I tried experimenting with bias, but I can't notice a difference. however, because I am colorblind, the problem may be my own and not colorRamp's.