【问题标题】:How do I stop ggplot2 from rotating my matrix 90 degrees?如何阻止 ggplot2 将矩阵旋转 90 度?
【发布时间】:2013-01-28 23:15:54
【问题描述】:

我正在尝试使用 ggplot2 创建热图,但我注意到当我绘制它时它似乎将矩阵向左旋转了 90 度。这很奇怪,使用coord_flip()t() 不起作用,因为它们将其旋转到左侧,而不是右侧(因此,它们不是更正,而是创建了一个旋转 180 度的热图)。是否有任何选项或技巧可以防止这种情况发生?以下是相关代码:

#this is needed to run custHeat
zeroInterval <- function(mat, colors){
  #modified version of findInterval such that zero is given its own category
  #This function takes intervals as left exclusive, right inclusive.
  #This is mostly so that intervals consisting of a single value will still be represented.
  intervalMat <- matrix(0, nrow=nrow(mat), ncol=ncol(mat))
  j <- 1
  for(i in 1:(length(colors) - 1)){
    if(colors[i] != colors[i+1]){
      intervalMat[mat>colors[i] & mat<=colors[i+1]] <- j
      j <- j + 1
    } else {
      intervalMat[mat==colors[i]] <- j
      j <- j + 1
    }
  }
  return(intervalMat)
}

#this actually plots the heatmap
custHeat <- function(M){

  #create color bins/ranges for skewed matrix
  color_bins <- c(-5, -4, -3, -2, -1, 0, 0, 1)
  colors <- c('#67001F', '#B2182B', '#D6604D', '#F4A582', '#FDDBC7', "#FFFFFF", '#C6DBEF')

  #create complete color palette
  color_palette <- colorRampPalette(colors)(length(color_bins) - 1)

  #This function assigns a number to each matrix value, so that it is colored correctly
  mod_mat <- zeroInterval(random_matrix, color_bins)


  ## remove background and axis from plot
  theme_change <- theme(
    plot.background = element_blank(),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_blank(),
    panel.background = element_blank(),
    panel.border = element_blank(),
    axis.line = element_blank(),
    axis.ticks = element_blank(),
    axis.text.x = element_blank(),
    axis.text.y = element_blank(),
    axis.title.x = element_blank(),
    axis.title.y = element_blank()
  )

  ## output the graphics
  ggplot(melt(mod_mat), aes(x = X1, y = X2, fill = factor(value))) +
    geom_tile(color = "black") +
    scale_fill_manual(values = color_palette, name = "") +
    theme_change
}

##create random matrix, skewed toward negative values
random_matrix <- matrix(runif(100, min = -5, max = 1), nrow = 10)
random_matrix[1,] <- 0 #zeros should be at the top row of the heatmap
custHeat(random_matrix)

【问题讨论】:

  • 我们没有zeroInterval这个函数。
  • 但无论如何,这本身并不 奇怪,它与 R 中创建类似图的基本上所有其他函数完全一致。来自image 上的文档:“请注意,图像将 z 矩阵解释为 f(x[i], y[j]) 值的表,因此 x 轴对应于行号,y 轴对应于列号,第 1 列位于底部,即矩阵的传统印刷布局逆时针旋转 90 度。”所以通常你需要以不同的方式填充你的矩阵来解决这个问题。
  • 这里的代码 sn-p 将矩阵顺时针旋转 90 度。 m &lt;- matrix(1:9, ncol=3); t(m)[,nrow(m):1]
  • 您是否尝试切换 x 和 y。您的示例不可重现,但我建议您查看 melt(model_mat) 返回的内容。
  • @joran 我添加了 zeroInterval 的代码。我注意到这在 R 中一直如此,但这似乎很奇怪。你知道理由是什么吗?

标签: r ggplot2 heatmap


【解决方案1】:

您可以通过将矩阵在另一个方向预旋转 90 度来抵消绘图功能的 90 度逆时针旋转:

## An example matrix
(m <- matrix(1:9, ncol=3))
#      [,1] [,2] [,3]
# [1,]    1    4    7
# [2,]    2    5    8
# [3,]    3    6    9

## The same matrix rotated 90 degrees clockwise
t(m)[,nrow(m):1]
#      [,1] [,2] [,3]
# [1,]    3    2    1
# [2,]    6    5    4
# [3,]    9    8    7

稍后添加:

一些 R 绘图函数使用与 image() 相同的约定,而其他的则不使用。 (请随时添加到此列表中。)

m <- matrix(1:9, ncol=3)


## ------- These plotting functions DO rotate a matrix --------

## image()
image(m, col=blues9)

## levelplot() -- a lattice equivalent of image()
library(lattice)    
levelplot(m, at=(1:10)-0.5, col.regions=blues9)

## Others
contour(m)
filled.contour(m, color=colorRampPalette(blues9))
persp(m) 
lattice::contourplot(m)
lattice::wireframe(m)  ## Nicely illustrates the logic of the indexing it uses


## ------- These plotting functions DO NOT --------

## imageRaster() -- a graphical primitive used by image(), among other functions 
plot(0:1, 0:1, type="n", xlab="", ylab="")
rasterImage(matrix(blues9, ncol=3), 0,0,1,1, interpolate=FALSE)

## grid.raster() -- imageRaster()'s counterpart in the grid graphical system
library(grid)
grid.raster(matrix(blues9, ncol=3), interpolate=FALSE)

## plot(raster()) in raster package
library(raster)
plot(raster(m), col=blues9)

【讨论】:

  • 谢谢,正是我需要的。我发现 image() 旋转矩阵非常令人困惑......这有什么用吗?
  • @Яaffael -- 我有一些关于原因的想法,但大多数情况下这只是你必须习惯的事情。如果您将矩阵中每个基准的(row,column) 坐标视为对应于在笛卡尔平面上绘制它的点的(x,y) 坐标,这会有点道理。行索引向下增加,列索引向右增加;相应的 x 轴和 y 轴值分别向右和向上增加。 (这对我来说有些道理,但我怀疑this may be the only reason that it does ;)。
猜你喜欢
  • 2020-09-04
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 2013-08-04
  • 1970-01-01
相关资源
最近更新 更多