Novice
Novice

Reputation: 307

Create quadratic matrix with lower triangle as heatmaps and upper triangle character data

I have the following (example) data, which I want to plot: matrix(c("Variable1",0.4,0.5,"string1","Variable2",0.3, "string2","string3","Variable3"),ncol=3)

I want to create heatmaps with the numbers 0.4,0.5,0.3 of the matrix and use the lower triangular:

  numeric<- matrix(c(1,0.4,0.5,0.4,1,0.3,0.5,0.3,1),ncol=3)
  require(graphics)
  require(grDevices)
  library(colorRamps)

  library(lattice)
  x <- seq(pi/4, 5*pi, length.out=10)
  y <- seq(pi/4, 5*pi, length.out=10)
  grid <- expand.grid(X=x, Y=y)

   myPanel <- function(x, y, z, ...) { 
   panel.levelplot(x,y,z,...)
   panel.text(x, y, round(z,2),cex=0.578,...)}
  levelplot(numeric,panel=myPanel)

On the upper triangle inclusive the diagonal of the heatmap, I want to have characters, with values "string1", "string2", "string3", "Variable1", "Variable2", "Variable3" on the same grid position as in the given matrix!

I thought of somehow creating a grid and using the image() function of the graphics package to color the numerics, but this doesn't work for me.

Do you have a simple and elegant function, where you just need the given matrix as input?

Upvotes: 2

Views: 1555

Answers (1)

Zuguang Gu
Zuguang Gu

Reputation: 1321

You may try ComplexHeatmap package by which you can self-define the heatmap body:

First create a symmetrix matrix:

set.seed(123)
mat = matrix(rnorm(100), 10)
colnames(mat) = letters[1:10]

mat2 = cor(mat)

Make clustering and adjust orders for both rows and columns:

od = hclust(dist(mat2))$order
mat2 = mat2[od, od]

Now we can self-define the heatmap. In following code, col controls how to map values to colors. Since clustering is already applied, we set cluster_rows and cluster_columns to FALSE. When type is set to none in gpar(), the heatmap is initialized but nothing is added, then we can use the self-defined function cell_fun to add graphic into it.

cell_fun will be applied to each small grid in the heatmap. In cell_fun, there are seven arguments:

  • j: column index in mat2
  • i: row index in mat2
  • x: position on the plot
  • y: position on the plot
  • w: width of the current grid
  • h: height of the current grid
  • col: filled color for the current grid

Use Heatmap() to generate the final heatmap:

Heatmap(mat2, col = colorRamp2(c(-1, 0, 1), c("green", "white", "red")),
    cluster_rows = FALSE, cluster_columns = FALSE,
    heatmap_legend_title = "cor", rect_gp = gpar(type = "none"), 
    cell_fun = function(j, i, x, y, w, h, col) {
        if(i > j) {
            grid.rect(x, y, w, h, gp = gpar(fill = col))
        } else if(j == i) {
            grid.text(labels[i], x, y)
        } else {
            grid.text(sprintf("%.2f", mat2[i, j]), x, y)
        }
        grid.rect(x, y, w, h, gp = gpar(fill = NA, col = "black"))
    })

enter image description here

Upvotes: 2

Related Questions