rggplot2plotrix

add text for each cell of a 2D matrix plot in R (plotrix and/or ggplot2)


A colored 2D matrix plot was created using the following codes:

library(plotrix)
testdf = data.frame(c(0,1,1),c(1,1,2),c(1,2,2))
color2D.matplot(testdf, 
                show.values = FALSE,
                axes = FALSE,
                xlab = "",
                ylab = "",
                vcex = 2,
                vcol = "black",
                extremes = c("red", "yellow", "green"))

However, this function can only show the numerical values within each cell, but what I want is some pre-specified texts (which can be provided from another data frame) added in each cell, like the screenshot below:

enter image description here

Is there a way in plotrix or some other R packages (e.g. ggplot2) that can make it? Thanks.


Solution

  • Here is a way using ggplot2.

    library(reshape2)
    library(ggplot2)
    
    testdf = data.frame(x = c(0,1,1),y = c(1,1,2),z = c(1,2,2))
    
    # Convert testdf dataframe to a matrix.
    df <- as.matrix(testdf)
    # Flip the matrix horizontally, and put into long format.
    df<-df[c(3:1), ,drop = FALSE] %>% 
      melt()
    
    # Create a new dataframe with the names for each tile.
    testdf_names <- data.frame(x = c("A","C","B"),y = c("AB","CD","C"),z = c("B","E","D"))
    #Then, do the same process as above by first putting into a matrix.
    df_names <- as.matrix(testdf_names)
    # Flip the matrix horizontally, and put into long format.
    df_names<-df_names[c(3:1), ,drop = FALSE] %>% 
      melt() %>% 
      dplyr::rename(names = value)
    
    # Join the dataframes together for plotting.
    df_new <- df %>% 
      dplyr::group_by(Var1, Var2) %>% 
      dplyr::left_join(df_names)
    
    # Plot.
    ggplot(df_new, aes(x = Var2, y = Var1)) + 
      geom_tile(aes(fill=as.factor(value)), color = "black", size = 1) + 
      scale_fill_manual(values=c("red", "yellow", "green")) +
      theme_void() + 
      theme(legend.position="none") +
      geom_text(aes(label=names), size = 30)
    

    enter image description here

    *Note: It isn't necessary to convert to a matrix; it is just a preference.