Change font type and add sub-superscripts or greek letters in the labels of a corrplot correlogram

2.1k views Asked by At

I want to make a correlogram with the corrplot R package.

The data used are like the table below

head(dat)
    pH      EC     NO3    NH4    Alpha     Beta
1 8.32 12.6174  5.5658 0.6406 641.1503 545.1455
2 8.19 11.9373 10.5631 0.9045 754.5042 514.9512
3 8.07 11.3534  6.8375 0.7977 744.9126 493.5152
4 8.19 12.4137  9.9584 0.9023 879.1580 655.9412
5 7.24  9.4181 10.0677 0.9382 637.0015 489.1772
6 7.75 10.3971 10.6647 1.0393 756.1199 517.5440
....    ....
....    ....
....    ....

But i want the numbers in the correlogram labels for NO3 and NH4 to be in subscript and for the Alpha and Beta to use the greek letters α and β.

The code I used to make the correlogram is below

M <- cor(dat) #create correlation matrix

# colors to be used
col2 <- colorRampPalette(c("#67001F", "#B2182B", "#D6604D", "#F4A582", 
                           "#FDDBC7","#FFFFFF", "#D1E5F0", "#92C5DE", 
                           "#4393C3", "#2166AC", "#053061"))

library(corrplot)

corrplot(M,method="square", order="original", col=col2(20), 
            cl.length=11,type="lower",tl.pos = "lt",tl.cex = 1,
            tl.col = "black", tl.offset = 0.4, tl.srt = 90,cl.pos="r",
            diag = FALSE)

correlogram

data

dat <- structure(list(pH = c(8.32, 8.19, 8.07, 8.19, 7.24, 7.75, 8.13, 
8.06, 7.91, 6.77, 5.28, 7.89, 7.68, 6.23, 8.31, 8.38, 8.31, 7.12, 
8.2, 8.33, 7.66, 6.24, 6.7, 7.84), EC = c(12.6174, 11.9373, 11.3534, 
12.4137, 9.4181, 10.3971, 14.7648, 13.7368, 15.7797, 7.1344, 
7.2042, 15, 11.7473, 8.087, 13.755, 13.5277, 14.8324, 8.0436, 
14.4983, 13.6894, 16.1245, 7.1204, 7.4364, 13.4685), NO3 = c(5.5658, 
10.5631, 6.8375, 9.9584, 10.0677, 10.6647, 11.6462, 12.5271, 
10.9805, 7.4731, 9.9492, 10.7479, 11.6753, 10.4071, 11.3829, 
12.2611, 11.9056, 10.2238, 9.8128, 11.1856, 4.3521, 4.6849, 7.3659, 
9.8142), NH4 = c(0.6406, 0.9045, 0.7977, 0.9023, 0.9382, 1.0393, 
1.1002, 1.1534, 1.2629, 1.0686, 1.0292, 1.1485, 1.058, 1.2891, 
1.0845, 1.1024, 1.1585, 1.0358, 0.9188, 0.9402, 0.9176, 0.8957, 
1.0508, 0.7891), Alpha = c(641.1503, 754.5042, 744.9126, 879.158, 
637.0015, 756.1199, 888.1357, 928.22, 982.75, 683.9139, 729.0595, 
764.2607, 673.8184, 493.8568, 708.114, 759.094, 1040.6623, 698.2495, 
819.0605, 710.4485, 655.0136, 805.2089, 645.5548, 831.6886), 
    Beta = c(545.1455, 514.9512, 493.5152, 655.9412, 489.1772, 
    517.544, 588.3099, 579.361, 564.1002, 483.3981, 511.9086, 
    440.1535, 497.5929, 328.9879, 506.202, 505.5201, 636.8879, 
    494.4532, 461.9742, 439.8569, 492.6054, 549.7177, 428.9918, 
    540.8364)), .Names = c("pH", "EC", "NO3", "NH4", "Alpha", 
"Beta"), class = "data.frame", row.names = c(NA, -24L))
3

There are 3 answers

1
Roman Luštrik On

The way I see it you have two options. One is to file a feature request at the author's package GitHub repository (this is what I would do) or hack the code to accommodate custom labels. I offer one partial solution below.

I added an extra argument to the function argument list called newcolnameslist and replaced a text() call for an mapply call.

if(tl.pos=="d"){
  ##if(type!="full") stop("type should be \"full\" if tl.pos is \"d\".")
  pos.ylabel <- cbind(m1:(m1+nn)-0.5, n2:n1)
  pos.ylabel <- pos.ylabel[1:min(n,m),]
  symbols(pos.ylabel[,1]+0.5, pos.ylabel[,2],add = TRUE,
          bg = bg, fg = addgrid.col,
          inches = FALSE, squares = rep(1, length(pos.ylabel[,1])))
  text(pos.ylabel[,1]+0.5, pos.ylabel[,2], newcolnames[1:min(n,m)],
       col = tl.col, cex = tl.cex, ...)
} else {
  mapply(pos.xlabel[, 1], pos.xlabel[, 2], newcolnameslist, FUN = function(p1, p2, lab) {
    text(p1, p2, lab, srt = tl.srt, 
         adj=ifelse(tl.srt==0, c(0.5,0), c(0,0)),
         col = tl.col, cex = tl.cex, offset=tl.offset, ...)
  })

  text(pos.ylabel[,1], pos.ylabel[,2], newrownames,
       col = tl.col, cex = tl.cex, pos=2, offset=tl.offset, ...)
}

I have done this only for column names. If you choose to go down this path, it's up to you to adapt the code for row names as well.

Here is proof of concept.

enter image description here

0
user20650 On

Perhaps a way around this is to set the colour of the labels in the corrplot function to white (tl.col = "white") and then just pass new text statements for the labels.

corrplot(M,method="square", order="original", col=col2(20), 
         cl.length=11,type="lower",tl.pos = "lt",tl.cex = 1,
         tl.col = "white", tl.offset = 0.4, tl.srt = 90,cl.pos="r",
         diag = FALSE)

text(1:5, 5.75, expression("pH", "EC", "NO"[3], "NH"[4], Alpha))
text(0, 5:1,  expression("EC", "NO"[3], "NH"[4], Alpha, Beta))

enter image description here

You could wrap this in a function where the x and y positions come from the number of rows / columns of your matrix

0
AJMA On

The new corrplot pre-release version (0.82) includes an easier way to use Plotmath expressions, as shown here