【问题标题】:Plotting only upper/lower triangle of a heatmap仅绘制热图的上/下三角形
【发布时间】:2011-01-20 02:01:46
【问题描述】:

在 maptplotlib 中,可以使用 imshow 函数创建相关矩阵的热图表示。根据定义,这样的矩阵围绕其主对角线对称,因此不需要同时呈现上下三角形。例如:
(来源:wisc.edu

上面的例子取自this site 不幸的是,我不知道如何在 matplotlib 中做到这一点。将矩阵的上/下部分设置为无会导致黑色三角形。我用谷歌搜索了“matplotlib 缺失值”,但找不到任何有用的东西

【问题讨论】:

  • 也许他们只是对它进行了Photoshop :)
  • 用另一个way回答

标签: python matplotlib plot


【解决方案1】:

doug 提供的答案的问题在于它依赖于颜色图将零值映射到白色的事实。这意味着不包含白色的颜色图没有用处。解决的关键是cm.set_bad函数。您可以使用 None 或使用 NumPy 屏蔽数组和 set_bad 将矩阵中不需要的部分屏蔽为白色,而不是默认的黑色。采用 doug 的例子,我们得到以下结果:

import numpy as NP
from matplotlib import pyplot as PLT
from matplotlib import cm as CM

A = NP.random.randint(10, 100, 100).reshape(10, 10)
mask =  NP.tri(A.shape[0], k=-1)
A = NP.ma.array(A, mask=mask) # mask out the lower triangle
fig = PLT.figure()
ax1 = fig.add_subplot(111)
cmap = CM.get_cmap('jet', 10) # jet doesn't have white color
cmap.set_bad('w') # default value is 'k'
ax1.imshow(A, interpolation="nearest", cmap=cmap)
ax1.grid(True)
PLT.show()

【讨论】:

  • 不错!也适用于pcolormesh,这就是我需要这个解决方案的目的。还要注意排除对角线以及将mask=NP.tri(A.shape[0],k=0)行中的k=-1更改为k=0
  • @Vlox,嗨。我想知道,我将如何掩盖上三角?
  • @chitown88 应该能够在绘图之前转置矩阵,所以只需将 .T 添加到行 A = NP.ma.array(A, mask=mask).T
  • @Vlox,好吧。我做的略有不同,但你的更有意义。
【解决方案2】:
import numpy as NP
from matplotlib import pyplot as PLT
from matplotlib import cm as CM

A = NP.random.randint(10, 100, 100).reshape(10, 10)
# create an upper triangular 'matrix' from A
A2 = NP.triu(A)
fig = PLT.figure()
ax1 = fig.add_subplot(111)
# use dir(matplotlib.cm) to get a list of the installed colormaps
# the "_r" means "reversed" and accounts for why zero values are plotted as white
cmap = CM.get_cmap('gray_r', 10)
ax1.imshow(A2, interpolation="nearest", cmap=cmap)
ax1.grid(True)
PLT.show()

【讨论】:

  • 感谢您的导入。可运行的示例非常有帮助。
【解决方案3】:

我得到的最佳答案来自 seaborn。输出是一个平滑而简单的图形。此函数将三角形保存到本地

def get_lower_tri_heatmap(df, output="cooc_matrix.png"):
    mask = np.zeros_like(df, dtype=np.bool)
    mask[np.triu_indices_from(mask)] = True

    # Want diagonal elements as well
    mask[np.diag_indices_from(mask)] = False

    # Set up the matplotlib figure
    f, ax = plt.subplots(figsize=(11, 9))

    # Generate a custom diverging colormap
    cmap = sns.diverging_palette(220, 10, as_cmap=True)

    # Draw the heatmap with the mask and correct aspect ratio
    sns_plot = sns.heatmap(data, mask=mask, cmap=cmap, vmax=.3, center=0,
            square=True, linewidths=.5, cbar_kws={"shrink": .5})
    # save to file
    fig = sns_plot.get_figure()
    fig.savefig(output)

【讨论】:

    【解决方案4】:

    您可以在一个上/下部分透明的白色矩阵上绘制

    a =random((10,10))
    imshow(a, interpolation='nearest')
    
    b = ones(a.shape+(4,)) # «white» matrix with alpha=1
    for i in range(a.shape[0]):
        for j in range(i, a.shape[1]):
            b[i,j,3] = 0   # upper triangle, alpha = 0
    imshow(b, interpolation='nearest')
    

    upper/lower triangle of a heatmap http://lh5.ggpht.com/_ZgVr3-a-Z00/S4P3_BWByKI/AAAAAAAAAXE/UsJpokz6LKE/pp.png

    【讨论】:

      【解决方案5】:

      使用seabornmatplotlibnumpy,一个快速的解决方案是:

      import matplotlib.pyplot as plt
      import seaborn as sns
      
      # Say your matrix object (e.g. np.array) is corr_mat
      
      # Get the upper triangle without the diagonal 
      corr_mat = np.triu(corr_mat, k=1)
      
      # Plot the heatmap
      ax = sns.heatmap(corr_mat)
      

      化妆请参考seaborn在线文档。

      【讨论】:

      • 这可行,但作为一个可能不受欢迎的副作用,它删除了列名,从而删除了执行xticklabels=corr.columns.values 的选项。一种解决方法是先声明名称(例如xnames=corr.columns.values),然后使用np.triu(),然后将xticklabels=xnames 作为参数发送
      • @tagoma 这实际上在对角线下方显示零。我如何删除这些单元格而不是显示零
      【解决方案6】:

      您可以使用此代码:

      from string import ascii_letters
      import numpy as np
      import pandas as pd
      import seaborn as sns
      import matplotlib.pyplot as plt
      
      sns.set_theme(style="white")
      
      # Generate a large random dataset
      rs = np.random.RandomState(33)
      d = pd.DataFrame(data=rs.normal(size=(100, 26)),
                       columns=list(ascii_letters[26:]))
      
      # Compute the correlation matrix
      corr = d.corr()
      
      # Generate a mask for the upper triangle
      mask = np.triu(np.ones_like(corr, dtype=bool))
      
      # Set up the matplotlib figure
      f, ax = plt.subplots(figsize=(11, 9))
      
      # Generate a custom diverging colormap
      cmap = sns.diverging_palette(230, 20, as_cmap=True)
      
      # Draw the heatmap with the mask and correct aspect ratio
      sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,
                  square=True, linewidths=.5, cbar_kws={"shrink": .5})
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多