Python seaborn绘制聚类热图如何按列值最高频次重排列
问题背景
我尝试对如下.csv格式的数据进行可视化:
Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9,Q10,Q11,Q12,Q13,Q14,Q15,Q16,Q17,Q18,Q19,Q20 4,4,2,2,4,2,3,5,3,4,2,5,2,1,4,4,2,1,5,2 2,2,4,4,4,2,2,2,4,4,2,4,2,2,3,2,2,4,5,2 4,5,4,1,4,2,2,4,4,3,2,2,2,1,2,4,4,2,5,4 3,4,2,4,4,2,2,2,4,3,2,4,4,3,3,4,2,4,5,1 4,4,3,2,4,3,4,5,4,3,1,5,3,2,4,2,2,3,4,2 4,5,2,3,5,1,3,4,3,3,1,2,4,4,5,4,1,4,5,4 5,5,5,2,4,3,2,4,4,2,2,4,4,2,4,2,2,4,4,5 4,4,3,1,5,3,2,4,2,2,1,4,4,2,4,1,2,5,5,3 1,3,5,2,4,4,3,1,4,4,2,3,1,4,3,4,3,3,4,1 3,3,5,2,4,2,4,4,3,4,1,5,4,2,1,2,2,4,5,2
当前使用的实现代码如下:
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv('data.csv') map = sns.clustermap(df, annot=True, linewidths=2, linecolor='yellow', metric="correlation", method="single") plt.show()
运行上述代码可得到默认聚类排序的热图。现需要对热图列进行重排,排序规则为按列方向上各响应值的出现频次排序:计算每列中出现频次最高的数值的频次,按该频次降序排列所有列。例如Q5列中数值4共出现8次,为所有列最高,应排在第一列;Q17、Q19列的最高值出现频次为7次,排在第二、第三位(二者相对顺序无要求)。
实现方案
seaborn.clustermap默认会同时对行、列做层次聚类并自动重排顺序,要实现自定义列排序,只需要两步:
- 提前按规则计算列顺序,重排DataFrame
- 传入
col_cluster=False参数关闭列方向的自动聚类,避免自定义的列顺序被覆盖,行方向的聚类效果可以完全保留。
完整可运行代码如下:
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv('data.csv') # 计算每列中最高频值的出现次数,按频次降序生成新的列顺序 col_max_count = df.apply(lambda col: col.value_counts().max(), axis=0) sorted_columns = col_max_count.sort_values(ascending=False).index df_sorted_col = df[sorted_columns] # 绘图时关闭列聚类,使用排好序的数据集 res = sns.clustermap( df_sorted_col, annot=True, linewidths=2, linecolor='yellow', metric="correlation", method="single", col_cluster=False ) plt.show()
运行后可以验证列顺序:Q5列(最高频值出现8次)排在最左侧,Q17、Q19(最高频值出现7次)紧随其后,完全符合排序规则。如果不需要保留行的聚类效果,也可以额外加row_cluster=False参数关闭行聚类。
内容的提问来源于stack exchange,提问作者Monika
相关产品推荐
相关产品推荐

