带注释的热图轴顺序取决于数据类型
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)
【讨论】:
以上是关于带注释的热图轴顺序取决于数据类型的主要内容,如果未能解决你的问题,请参考以下文章
通过 geom_tile ggplot R 的热图 - 正确组织每月因子的 y 轴水平