【问题标题】:How do I graph a matrix using ggplot如何使用 ggplot 绘制矩阵图
【发布时间】:2021-10-10 15:25:41
【问题描述】:

我想可视化一个矩阵。

MAT <-  matrix(c(100, 7, 0, 0, 49, 0, 0, 0, -49), nrow = 3, ncol = 3)

> MAT
     [,1] [,2] [,3]
[1,]  100    7    0
[2,]    0   49    0
[3,]    0    0  -49

但是,标准方法不能正确地对小数字进行着色,并且使用的边距大得无法接受。

image(t(MAT[nrow(MAT):1,] ), axes=FALSE)

我想使用geom_raster()geom_tile()ggplot 中绘制这个矩阵。

【问题讨论】:

    标签: r ggplot2 matrix


    【解决方案1】:

    以下功能允许您调整颜色。通过使用将零表示为白色的颜色渐变,很容易将小数字检测为与白色的细微差异。

    警告:vizMat() 仅适用于方阵。

    警告:vizMat() 在昏暗 > 99 时中断;这与解析和排序列有关。

    library(tidyverse)
    
    vizMat <- function(thisMAT) {
      n_max <- dim(thisMAT)[1]
      VNN <- paste0("V", sprintf("%02d",1:n_max))
      df <- rev(as.data.frame(t(thisMAT)))
      names(df) <- VNN
      df %>%
        mutate(row_num = VNN) %>% 
        select(row_num, everything()) %>% 
        pivot_longer(-row_num) %>% 
        ggplot(aes(x=row_num, y=name, fill=value)) +
        geom_raster(show.legend = F) +
        scale_fill_gradient2(low = "red",
                             mid = "white",
                             high = "navy", midpoint = .02) +
        theme_void()
    }
    
    MAT <-  matrix(c(100, 7, 0, 0, 49, 0, 0, 0, -49), nrow = 3, ncol = 3)
    vizMat(MAT)
    

    【讨论】:

      【解决方案2】:

      您可以将ggplot2 中的geom_tile() 几何与scale_fill_fermenter() 一起使用。您可以调整标尺的 breaks 参数,使其具有您想要的不同断点的任何值(添加更大/更小的限制可防止标尺末端的超长类别)。

      graphmat <- function(MAT) {
          mat <- as_tibble(MAT, .name_repair = ~paste0("V", 1:ncol(MAT))) %>%
              mutate(row = 1:nrow(.)) %>%
              pivot_longer(cols = starts_with("V"),
                           names_pattern = "V(.+)", names_to = "col") %>%
              mutate(col = as.numeric(col))
          ggplot(mat, aes(x = row, y = col, fill = value)) +
              geom_tile() +
              scale_fill_fermenter(
                  breaks = c(-50, -5, 0, 5, 99),
                  limits = c(-50.001, 99.001),
                  palette = "RdBu"
              ) +
              scale_y_reverse() +
              theme_minimal() +
              theme(
                  legend.position = 'top',
                  legend.key.width = unit(70, "pt"),
                  legend.key.height = unit(10, "pt"),
              )
      }
      
      MAT <-  matrix(c(100, 7, 0, 0, 49, 0, 0, 0, -49), nrow = 3, ncol = 3)
      graphmat(MAT) 
      

      BIGMAT <-  matrix(round(runif(500^2)*100, 2), nrow = 500, ncol = 500)
      graphmat(BIGMAT)
      

      【讨论】:

      • 感谢您的努力,除了获得对矩阵结构的直觉外,我还想保持其方向(您已经做到了),有效利用空间(留有小边距),以及进行有意义的分色。
      • 代码还需要能够扩展到大型矩阵。您的解决方案不会超过 10;但是,我目前的解决方案不能超过 100。
      • 我真的很喜欢您使用 .name_repair 和 names_pattern 参数。我计划在升级我的版本时使用这些。谢谢!
      • 谢谢!单元格数量的问题是由于pivot_longernames_pattern 参数中的正则表达式不正确造成的。它必须是names_pattern = V(.+)`(注意“+”)。解决这个问题,解决方案应该足够大以覆盖非常大的矩阵。我已经编辑了答案以显示两者。
      【解决方案3】:

      heatmap 呢?

      heatmap(MAT)
      

      【讨论】:

      • 我想可视化一个矩阵以获得对其结构的直觉。为此,保持其方向、有效利用空间(留出小边距)并进行有意义的分色非常重要。
      猜你喜欢
      • 2019-11-23
      • 1970-01-01
      • 1970-01-01
      • 2016-10-20
      • 1970-01-01
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多