如何并排可视化Numpy数组中原始数据与聚类成员关系?
并排可视化原始数据热力图与类别成员概率图
我有一个尺寸为13500、形状为(15, 30, 30)的Numpy数组my_original_data,并基于其类别成员关系生成了包含三个特征的DataFramemy_cluster_df。希望能将原始数据(仅聚焦单一层的30×30热力图)与三类成员概率图并排可视化,直观展示每个网格对应的各类别成员占比。
尝试代码
import matplotlib.pyplot as plt import pandas as pd import numpy as np from sklearn.mixture import GaussianMixture my_original_data = np.random.rand(13500).reshape(15, 30, 30) rng = np.random.default_rng(42) X = np.c_[ rng.normal(loc=25, scale=15, size=4500), rng.normal(loc=65, scale=15, size=4500), rng.normal(loc=115, scale=15, size=4500),].reshape(-1, 1) model = GaussianMixture(n_components=3, random_state=42) model.fit(X) my_cluster_df = pd.DataFrame(np.round(model.predict_proba(X), 3), columns=["Class_Membership_1", "Class_Membership_2", "Class_Membership_3"]) fig = plt.figure() ax = fig.add_subplot(111, projection="3d") x = np.array(my_cluster_df["Class_Membership_1"]) y = np.array(my_cluster_df["Class_Membership_2"]) z = np.array(my_cluster_df["Class_Membership_3"]) ax.scatter(x, y, z, marker="s", c=my_cluster_df.index, s=40, cmap="RdBu") plt.show() side_by_side = np.hstack([ np.array(my_original_data[0, 0:30, 0:30].reshape(30, 30)), np.array(my_cluster_df["Class_Membership_1"].head(30 * 30).to_numpy().reshape(30, 30)), np.array(my_cluster_df["Class_Membership_2"].head(30 * 30).to_numpy().reshape(30, 30)), np.array(my_cluster_df["Class_Membership_3"].head(30 * 30).to_numpy().reshape(30, 30)) ])
期望效果为:原始数据热力图、三类成员概率热力图并排展示(对应示例图:原始数据热力图、类别1成员概率图、类别2成员概率图、类别3成员概率图)。
解决方案代码
通过Matplotlib的子图布局可实现需求,具体代码如下:
import matplotlib.pyplot as plt import pandas as pd import numpy as np from sklearn.mixture import GaussianMixture # 生成数据(与原代码逻辑一致) my_original_data = np.random.rand(13500).reshape(15, 30, 30) rng = np.random.default_rng(42) X = np.c_[rng.normal(loc=25, scale=15, size=4500), rng.normal(loc=65, scale=15, size=4500), rng.normal(loc=115, scale=15, size=4500)].reshape(-1, 1) model = GaussianMixture(n_components=3, random_state=42) model.fit(X) my_cluster_df = pd.DataFrame(np.round(model.predict_proba(X), 3), columns=["Class_Membership_1", "Class_Membership_2", "Class_Membership_3"]) # 匹配原始数据结构,提取对应层的概率数据 layer_data = my_original_data[0] # 取第一层的30×30原始数据 class1_probs = my_cluster_df["Class_Membership_1"].values.reshape(15,30,30)[0] class2_probs = my_cluster_df["Class_Membership_2"].values.reshape(15,30,30)[0] class3_probs = my_cluster_df["Class_Membership_3"].values.reshape(15,30,30)[0] # 创建1行4列的子图布局 fig, axes = plt.subplots(1, 4, figsize=(20, 5)) # 绘制原始数据热力图 im1 = axes[0].imshow(layer_data, cmap='viridis') axes[0].set_title('原始数据热力图') plt.colorbar(im1, ax=axes[0]) # 绘制类别1成员概率热力图 im2 = axes[1].imshow(class1_probs, cmap='viridis') axes[1].set_title('类别1成员概率') plt.colorbar(im2, ax=axes[1]) # 绘制类别2成员概率热力图 im3 = axes[2].imshow(class2_probs, cmap='viridis') axes[2].set_title('类别2成员概率') plt.colorbar(im3, ax=axes[2]) # 绘制类别3成员概率热力图 im4 = axes[3].imshow(class3_probs, cmap='viridis') axes[3].set_title('类别3成员概率') plt.colorbar(im4, ax=axes[3]) # 自动调整子图间距,避免元素重叠 plt.tight_layout() plt.show()
代码说明
- 将概率值按原始数据的(15,30,30)形状重塑,确保每个网格位置一一对应;
- 使用
subplots创建1行4列的子图布局,通过imshow绘制热力图; - 为每个子图添加标题和颜色条,方便对比解读各网格的数值分布;
- 调用
tight_layout()自动调整子图间距,优化展示效果。
内容的提问来源于stack exchange,提问作者bluered_earth
相关产品推荐
相关产品推荐

