绘制热图的上/下三角形部分

29
在Matplotlib中,可以使用imshow函数创建一个热力图表示相关矩阵。根据定义,这样的矩阵在其主对角线周围是对称的,因此不需要同时展示上三角和下三角。例如: correlation matrix
(来源:wisc.edu) 上面的例子来自这个网站。 不幸的是,我无法弄清楚如何在Matplotlib中实现这一点。将矩阵的上/下部分设置为None会导致黑色三角形。我已经搜索了“matplotlib missing values”,但没有找到有用的信息。

2
也许他们只是用Photoshop修改了它 :) - endolith
1
请以另一种方式回答:链接 - teddcp
6个回答

32
问题在于doug提供的答案依赖于colormap将零值映射为白色的事实。这意味着不包括白色颜色的colormap是无用的。解决方案的关键是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
@Vlox,您好。我在想,如何屏蔽掉上三角形? - chitown88
1
@chitown88 在绘图前应该能够直接转换矩阵,所以只需在行 A = NP.ma.array(A, mask=mask).T 后添加 .T 即可。 - Vlox
@Vlox,啊好的。我做了一点不同,但你的更有意义。 - chitown88
这非常有用 - 谢谢。对于那些想要使用“新的”颜色映射(如“plasma”,“rocket”,“magma”,“inferno”,“viridis”)的人来说,我有一个小建议,你可以跳过cmap.set_bad()这一步,因为它们已经将其设置为白色。你可以通过打印cmap.get_bad()来验证。你应该会得到array([0., 0., 0., 0.]) - LeviAckerman

13

我得到的最佳答案来自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)

下三角形


11
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()

plot


2
感谢您包含您的导入。可运行的示例非常有帮助。 - jcdyer

2

2
使用 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 的在线文档进行美化。

1
这段代码是可以运行的,但是有一个潜在的问题:它会去掉列名,并因此无法使用xticklabels=corr.columns.values选项。解决方法是首先声明名称(例如xnames=corr.columns.values),然后使用np.triu(),最后将xticklabels=xnames作为参数发送。 - Mitchell van Zuylen
1
@tagoma 这实际上显示了对角线以下的零。我该如何删除这些单元格,而不是显示零? - Khurram Majeed

1

you can use this code:

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})

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community
这是Seaborn示例库绘制对角线相关矩阵的副本,最好将其作为参考提及。 - Mario

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接