带注释的热图轴顺序取决于数据类型

Posted

技术标签:

【中文标题】带注释的热图轴顺序取决于数据类型【英文标题】:Plotly annotated heatmap axis order depends on data type 【发布时间】:2021-09-17 05:23:48 【问题描述】:

我正在尝试使用带注释的热图在 Plotly 中绘制混淆矩阵。现在我注意到,由于某种原因,Y 轴会根据标签的数据类型翻转,即使我将数据类型强制为字符串也是如此。

下面的代码将提供两个图,其中第二个图与第一个图相比具有倒置的 Y 轴。第一个是我希望它显示的方式,无论类名的数据类型如何。

顺序在哪里更改,我如何强制它保持在提供的列表顺序中?

'''

import numpy as np

confm = array([[10, 4,  0,  1,  0],
               [1, 20, 10,  1,  0],
               [0,  7, 30,  3,  0],
               [0,  1,  1, 40,  2],
               [1,  1,  2,  2, 50]])

labels = [1, 2, 3, 4, 5]


import plotly.graph_objects as go
import plotly.figure_factory as ff


def plot_matrix(confm, class_names):

    z =  np.round(confm, 2)  # for readability
    
    class_names = [str(c) for c in class_names]  # force all to string

    
    fig = ff.create_annotated_heatmap(z,
                                      colorscale='reds',
                                      xtype='array',
                                      ytype='array',
                                      x=class_names,
                                      y=class_names[::-1],  # invert order
                                     )
    
    

    fig.update_layout(
            title='Confusion matrix',
            width=600,
            height=600,
            margin=dict(pad=20),
            plot_bgcolor='white',
            xaxis=dict(title='Prediction',
                       showticklabels = True,
                       side='bottom',
                       tickmode='array',
                       tickvals=class_names,
                       ticktext=class_names),
            yaxis=dict(title='Truth',
                       tickmode='array',
                       tickvals=class_names,
                       ticktext=class_names[::-1])
                    )


    fig.show()


plot_matrix(confm, [1, 2, 3, 4, 5])
plot_matrix(confm, ['a', 'b', 'c', 'd', 'e'])

'''

【问题讨论】:

【参考方案1】:

很明显 plotly 库在可能的情况下会转换回整数/数字。为了保持行为相同,您可以

    class_names = [str(c)+"\0" for c in class_names]  # force all to string

只需附加一个 null ascii 字符,然后防止它被转换回数字。

【讨论】:

这实际上似乎产生了与预期结果完全相反的结果(加上一些不受欢迎的 ascii 字符)。此外,转换并不能真正一致地或逻辑地工作:只有 Y 轴被重新排序,而 X 轴被单独保留。 我正在使用 plotly 5.1.0,两者都产生相同的图表,标签从左上角开始。数字标签不起作用,plotly 试图从零开始索引。顺便说一句,如果不更改为 confm = np.array(...),您的示例代码将无法正常工作 在 5.1.0 和 y 标签的反转被移除后,我至少得到了相同的图表,但对角线错误。我添加了 z = z[::-1] 来反转它,这似乎使它完全起作用。唯一剩下的怪癖是它拒绝混合数据类型。【参考方案2】:

这适用于直接来自 scikit 的 confm,无需经过转换。唯一仍然打破它的是混合标签数据类型:

import plotly.graph_objects as go
import plotly.figure_factory as ff
from sklearn.metrics import confusion_matrix
   

def plot_matrix(confm, class_names):

    z = np.round(confm, 2)
    
    z = z[::-1]
      
    fig = ff.create_annotated_heatmap(z,
                                      colorscale='reds',
                                      xtype='array',
                                      ytype='array',
                                      x=class_names,
                                      y=class_names,
                                     )
    
    

    fig.update_layout(
            title='Confusion matrix',
            width=600,
            height=600,
            margin=dict(pad=20),
            plot_bgcolor='white',
            xaxis=dict(title='Prediction',  # Prediction
                       showticklabels = True,
                       side='bottom',
                       tickmode='array',
                       tickvals=class_names,
                       ticktext=class_names),
            yaxis=dict(title='Truth',  # Truth
                       tickmode='array',
                       tickvals=class_names,
                       ticktext=class_names[::-1]
                      )
                    )


    fig.show()


truth = ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'a', 'b', 'b'] 
pred = ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'a', 'a']
labels = ['a', 'b'] 

confm = confusion_matrix(truth, pred, labels)

plot_matrix(confm, labels)

【讨论】:

以上是关于带注释的热图轴顺序取决于数据类型的主要内容,如果未能解决你的问题,请参考以下文章

带有多种配色方案的带注释热图

具有二进制颜色编码和原始输入注释的 seaborn 热图

通过 geom_tile ggplot R 的热图 - 正确组织每月因子的 y 轴水平

Plotly:如何在带注释的热图中舍入显示文本但在悬停时保持完整格式?

python 带注释的热图

抑制绘图子图中的y轴标签,注释未对齐