【问题标题】:Adjust subplot with heatmaps使用热图调整子图
【发布时间】:2019-05-30 03:53:29
【问题描述】:

我有一个带有混淆矩阵的SubplotsHeatMap

我想调整图表以使其更具可读性并执行以下操作:

1) 在“目标”列上方添加一个大标题

2) 添加一个大的 Ylabel 'Predictions'

3) 每一列只有一个大图例,因为它们显示的是相同的东西

4 ) 为每一列添加列名 ['Train CM', 'Train Norm CM', 'Validation CM', 'Validation Norm CM'] 和行名称 [f'Epoch {i}' for i in range(n_epoch)]。我确实喜欢here 但只适用于列而不适用于行,我不知道为什么。

我的代码:

cols = ['Train CM', 'Train Norm CM', 'Validation CM', 'Validation Norm CM']
rows = [f'Epoch {i}' for i in range(n_epoch)]

f, axes  = plt.subplots(nrows = n_epoch, ncols = 4, figsize=(40, 30))
for ax, col in zip(axes [0], cols):
    ax.set_title(col, size='large')

for ax, row in zip(axes[:,0], rows):
    ax.set_ylabel(row, rotation=0, size='large')

f.tight_layout()

for e in range(n_epoch):
    for c in range(4):
        # take conf matrix from lists cm_Train or cm_Validation of ConfusionMatrix() objects
        if c == 0:
            cm = np.transpose(np.array([list(item.values()) for item in cm_Train[e].matrix.values()]))
        elif c == 1:
            cm = np.transpose(np.array([list(item.values()) for item in cm_Train[e].normalized_matrix.values()]))
        elif c == 2:
        cm = np.transpose(np.array([list(item.values()) for item in cm_Validation[e].matrix.values()]))
    else:
        cm = np.transpose(np.array([list(item.values()) for item in cm_Validation[e].normalized_matrix.values()]))
    sns.heatmap(cm, annot=True, fmt='g', ax = axes[e, c], linewidths=.3)

【问题讨论】:

    标签: python python-3.x matplotlib subplot


    【解决方案1】:

    因为我没有您的数据,所以我提出了一个带有空图的解决方案。这是你想要的吗:

    n_epoch = 4
    cols = ['Train CM', 'Train Norm CM', 'Validation CM', 'Validation Norm CM']
    rows = [f'Epoch {i}' for i in range(n_epoch)]
    
    f, axes  = plt.subplots(nrows = n_epoch, ncols = 4, figsize=(12, 8))
    
    f.text(0, 0.5, 'Predictions', ha='center', va='center', fontsize=20, rotation='vertical')
    plt.suptitle("One big title", fontsize=18, y=1.05)
    
    for ax, col in zip(axes [0], cols):
        ax.set_title(col, size='large')
    
    for ax, row in zip(axes[:, 0], rows):
        ax.set_ylabel(row, size='large')
    
    plt.tight_layout()    
    

    放置颜色条:您可以在此处放置跨越每列所有行的颜色条。但是,这里的tight_layout() 不兼容,因此您必须将其关闭。

    f, axes  = plt.subplots(nrows = n_epoch, ncols = 4, figsize=(12, 8))
    
    for i, ax in enumerate(axes.flat):
        im = ax.imshow(np.random.random((20,20)), vmin=0, vmax=1)
        if i%4 == 0:
            f.colorbar(im, ax=axes[:,int(i/4)].ravel().tolist(), aspect=30, pad=0.05)    
    
    f.text(0.08, 0.5, 'Predictions', ha='center', va='center', fontsize=20, rotation='vertical')
    plt.suptitle("One big title", fontsize=18)
    
    for ax, col in zip(axes [0], cols):
        ax.set_title(col, size='large')
    
    for ax, row in zip(axes[:, 0], rows):
        ax.set_ylabel(row, size='large')
    

    【讨论】:

    • 看起来不错,但仍然没有显示 y_labels
    • 您还没有明确说明要在何处以及如何显示 y 标签。目前 Epoch0、Epoch 1 等是 y 标签
    • 啊,是的,也许我解释得不好,每一行都是一个纪元,所以整个第一行的 y_label 应该是纪元 1,第二行纪元 2 等等
    • 好的,我编辑了我的解决方案。检查编辑的图形。顺便说一句,你应该在你的问题中问一个通常关于 SO 的问题。在这里,您提出了 4 个不同的问题。
    • 我看到了您的更改,它与我提供的链接中的类似,但由于某种原因,y_labels 没有出现
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 2022-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    相关资源
    最近更新 更多