使用 seaborn 和 matplotlib 对热图进行注释的绘图

Posted

技术标签:

【中文标题】使用 seaborn 和 matplotlib 对热图进行注释的绘图【英文标题】:Annotated plot over heatmap with seaborn and matplotlib 【发布时间】:2021-03-14 01:38:59 【问题描述】:

我不能在热图上叠加绘图(热图应该是海底绘制的)。

这是我的小数据示例

mat = [
    [1,2,3,1,1,2,2,1,5],
    [3,2,2,1,1,2,2,1,5],
    [6,2,8,2,1,0,0,4,2],
    [3,1,2,3,1,2,4,1,4],
    [3,1,9,4,1,3,2,1,5],
]

iters = [1, 2, 8, 16, 32, 128, 256, 512, 1024] # iterations for x-axis
names = [1, 2, 3, 4, 5] # 5 clusters 
maxim = [1, 1, 3, 5, 1, 4, 4, 5, 1] # maximum cluster at iter 
conc = ["dog", "spoon", "table", "bike", "hat", "hat", "porch", "sweater", "bird"] # maximum concept in cluster  for annotation

和绘图

def plot_cluster_heatmap_over_iters(iter_scores, iters, cluster_names, maximum_cluster, max_concepts):
    import seaborn as sns
    ax = sns.heatmap(iter_scores, cmap="gist_yarg")
    plt.xticks(range(len(iters)), iters, rotation=90);
    plt.yticks(range(len(cluster_names)), cluster_names, rotation=0);
    ax.set_yticklabels(ax.get_yticks(), size=7)

    
    plt.plot(iters, maximum_cluster, marker='o', )
    #annotate markers
    prev_cl = None
    for it, ci, cl in zip(iters, maximum_cluster, max_concepts):
        if prev_cl is None or prev_cl != cl:    
            plt.annotate(cl, (it, ci), rotation=40, size=12)
            prev_cl = cl
    plt.show()
    
plot_cluster_heatmap_over_iters(mat, iters, names, maxim, conc)

但我有类似的错误

ValueError: Image size of 76240x871 pixels is too large. It must be less than 2^16 in each direction.

有人可以帮助我改进我的代码,使其正常工作并完成工作(我敢打赌几乎没有问题)吗? 谢谢

【问题讨论】:

【参考方案1】:

错误的原因是我们在热图上标注的位置信息超出了热图的数据范围。我们创建了一个新的 x 轴值并更改了格式以基于它进行注释。 iters 大于等于 8 的值超出了图形范围。

import matplotlib.pyplot as plt
import numpy as np

mat = [
    [1,2,3,1,1,2,2,1,5],
    [3,2,2,1,1,2,2,1,5],
    [6,2,8,2,1,0,0,4,2],
    [3,1,2,3,1,2,4,1,4],
    [3,1,9,4,1,3,2,1,5],
]

iters = [1, 2, 8, 16, 32, 128, 256, 512, 1024] # iterations for x-axis
names = [1, 2, 3, 4, 5] # 5 clusters 
maxim = [1, 1, 3, 5, 1, 4, 4, 5, 1] # maximum cluster at iter 
conc = ["dog", "spoon", "table", "bike", "hat", "hat", "porch", "sweater", "bird"] # maximum concept in cluster  for annotation
maxlen = np.arange(1,10)

def plot_cluster_heatmap_over_iters(iter_scores, iters, cluster_names, maximum_cluster, max_concepts, maxl):
    import seaborn as sns
    ax = sns.heatmap(iter_scores, cmap="gist_yarg")
    plt.xticks(range(len(iters)), iters, rotation=90);
    plt.yticks(range(len(cluster_names)), cluster_names, rotation=0);
    ax.set_yticklabels(ax.get_yticks(), size=7)

    
    plt.plot(iters, maximum_cluster, marker='o')
#     #annotate markers
    prev_cl = None
    for it, ci, cl, ma in zip(iters, maximum_cluster, max_concepts, maxl):
        if prev_cl is None or prev_cl != cl:    
            plt.annotate(cl, (ma, ci), rotation=40, size=12, xycoords='data')
            prev_cl = cl
    plt.show()
    
plot_cluster_heatmap_over_iters(mat, iters, names, maxim, conc, maxlen)

【讨论】:

我不能接受你的回答,因为桌子、自行车、帽子和鸟没有被情节联系起来,甚至鸟都飞出了图表。这显然不是一张合适的图表。但无论如何,我已经解决了问题 接受与否由您决定。您指出了与问题解决方案不同的挑战,但您的代码不是原因吗?【参考方案2】:

这是我的解决方案。关键是使用range(len(iters))进行注释和绘图,而不是iters

#test
mat = [
    [1,2,3,1,1,2,2,1,5],
    [3,2,2,1,1,2,2,1,5],
    [6,2,8,2,1,0,0,4,2],
    [3,1,2,3,1,2,4,1,4],
    [3,1,9,4,1,3,2,1,5],
]

iters = [1, 2, 8, 16, 32, 128, 256, 512, 1024] # iterations for x-axis
names = [1, 2, 3, 4, 5] # 5 clusters 
maxim = [1, 1, 3, 5, 1, 4, 4, 5, 1] # maximum cluster at iter 
conc = ["dog", "spoon", "table", "bike", "hat", "hat", "porch", "sweater", "bird"] # maximum concept in cluster  for annotation

def plot_cluster_heatmap_over_iters(iter_scores, iters, cluster_names, maximum_cluster, max_concepts):
    import seaborn as sns
    ax = sns.heatmap(iter_scores, cmap="gist_yarg")
    plt.xticks(range(len(iters)), iters, rotation=90);
    plt.yticks(range(len(cluster_names)), cluster_names, rotation=0);
    ax.set_yticklabels(ax.get_yticks(), size=7)

    plt.plot(range(len(iters)), maximum_cluster, marker='o')
    #annotate markers
    prev_cl = None
    for it, ci, cl in zip(range(len(iters)), maximum_cluster, max_concepts):
        if prev_cl is None or prev_cl != cl:    
            plt.annotate(cl, (it, ci), rotation=40, size=12, xycoords='data')
            prev_cl = cl
    plt.show()
    
plot_cluster_heatmap_over_iters(mat, iters, names, maxim, conc)

【讨论】:

以上是关于使用 seaborn 和 matplotlib 对热图进行注释的绘图的主要内容,如果未能解决你的问题,请参考以下文章

seaborn + matplotlib 画图(四): 自定义子图+拟合线

使用 seaborn 或 matplotlib 分组箱线图的数据格式

数据分析 - seaborn 模块

如何在 seaborn / matplotlib 中绘制和注释分组条形

使用 Seaborn 和 Matplotlib 在热图和线图的共享子图中对齐 x 轴刻度

使用 matplotlib 和 seaborn 在多元时间序列图中突出显示时间间隔