如何在mpl_toolkits 3D散点图中使用seaborn tab10_r配色
配色不一致原因
直接向matplotlib的cmap参数传入tab10_r字符串时,matplotlib会将传入的类别值做0-1范围归一化,按连续色映射逻辑取色;而seaborn的pairplot使用tab10_r时,会根据实际类别数量,从调色板头部按顺序取出对应个数的离散分类色,二者取色逻辑不匹配,最终视觉效果就会出现偏差。
修复方案
核心是对齐seaborn的取色逻辑,手动构造和seaborn输出完全一致的离散色映射,避免matplotlib自动做连续色归一化:
- 调用
sns.color_palette('tab10_r', 类别总数)拿到和pairplot完全相同的离散色序列 - 将色序列转为matplotlib支持的
ListedColormap对象 - 传入
scatter3D时通过vmin、vmax参数锁定颜色映射的数值范围,防止自动归一化导致的颜色错位
修正后的可运行代码如下:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits import mplot3d import seaborn as sns from matplotlib.colors import ListedColormap # 配置项:按实际类别数量修改 class_count = 3 # 对齐seaborn取色逻辑,获取完全一致的tab10_r分类色 sns_palette = sns.color_palette('tab10_r', class_count) cmap = ListedColormap(sns_palette) # 修复原代码中重复创建空画布的问题 plt.figure(figsize=(15, 12)) ax = plt.axes(projection="3d") x = x_pca[:, 0] y = x_pca[:, 1] z = x_pca[:, 2] y_train_new = y_train_orig.argmax(1) ax.scatter3D( x, y, z, c=y_train_new, marker='o', alpha=0.6, s=55, cmap=cmap, # 锁定映射范围,和类别标签的取值范围完全对应 vmin=0, vmax=class_count - 1, edgecolor='k' ) plt.title("3D Scatterplot: 95% of the variability captured", pad=15) ax.set_xlabel('First principal component') ax.set_ylabel('Second principal component') ax.set_zlabel('Third principal component') # 可选:添加分类图例,和seaborn pairplot的图例样式对齐 plt.legend( handles=ax.collections[0].legend_elements()[0], labels=[f'Class {i}' for i in range(class_count)] ) plt.show()
额外说明:如果类别标签不是从0开始的连续整数,可以直接给每个类别匹配对应颜色后,传入颜色列表给
c参数,完全绕开matplotlib的自动色映射流程,能100%保证配色和seaborn输出效果一致。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

