You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Plotly绘制聚类轮廓图时遇单值无法迭代报错问题

解决聚类轮廓图绘制的TypeError问题

问题原因

你用sklearn.metrics.silhouette_score得到的是全局平均轮廓系数,是单个numpy.float64值,而绘制轮廓图需要每个样本的轮廓系数,直接迭代这个单值就会触发TypeError: 'numpy.float64' object is not iterable。

修复方案

改用sklearn.metrics.silhouette_samples函数获取每个样本的轮廓系数,再结合matplotlib绘制标准轮廓图,同时确保concat_omics_df的索引和subtype_labels完全匹配。

完整代码示例

import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import silhouette_samples, silhouette_score

# 对齐数据与标签的索引,确保样本和标签一一对应
aligned_df = concat_omics_df.loc[subtype_labels.index]
X = aligned_df.values
labels = subtype_labels.values

# 计算全局平均轮廓系数,以及每个样本的轮廓系数
sil_avg = silhouette_score(X, labels)
sil_samples = silhouette_samples(X, labels)

# 绘制轮廓图
n_clusters = len(np.unique(labels))
y_lower = 10  # 底部留白

plt.figure(figsize=(8, 6))
for i in range(n_clusters):
    # 提取当前簇的样本轮廓系数并排序
    cluster_sil = sil_samples[labels == i]
    cluster_sil.sort()
    
    cluster_size = cluster_sil.shape[0]
    y_upper = y_lower + cluster_size
    
    # 填充簇的轮廓区域
    plt.fill_betweenx(np.arange(y_lower, y_upper), 0, cluster_sil, alpha=0.7)
    # 标注簇编号
    plt.text(-0.05, y_lower + 0.5 * cluster_size, str(i+1))
    
    y_lower = y_upper + 10  # 簇之间留空

# 绘制全局平均轮廓系数的虚线
plt.axvline(x=sil_avg, color="red", linestyle="--")
plt.xlabel("轮廓系数值")
plt.ylabel("簇编号")
plt.title(f"聚类轮廓图 (平均轮廓系数: {sil_avg:.2f})")
plt.tick_params(axis='y', which='both', left=False, labelleft=False)  # 隐藏y轴刻度
plt.show()

关键说明

  • 索引对齐:通过loc方法确保concat_omics_df的行顺序和subtype_labels完全一致,避免样本与标签不匹配的问题。
  • silhouette_samples:返回与样本数量一致的数组,每个元素对应单个样本的轮廓系数,这是绘图的核心数据。
  • 绘图逻辑:按簇排序系数后填充区域,同时标注簇编号和平均系数线,符合标准轮廓图的样式。

内容的提问来源于stack exchange,提问作者Anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:32:37