如何在Python的3D图中堆叠多组小提琴图(多传感器多分类场景)
3D堆叠小提琴图实现方案
核心思路
借助Matplotlib的3D坐标轴,将8个传感器对应的三类小提琴图分别绘制在不同的Z轴高度上,通过调整X轴偏移量和图形透明度,实现清晰的堆叠效果。
实现代码示例
import matplotlib.pyplot as plt import seaborn as sns import numpy as np # 模拟8个传感器的三类数据(替换为你的真实数据集) np.random.seed(42) sensor_data = [] for _ in range(8): p1 = np.random.normal(loc=-1, scale=0.8, size=1000) p2 = np.random.normal(loc=0, scale=1.2, size=1000) p3 = np.random.normal(loc=1, scale=0.9, size=1000) sensor_data.append([p1, p2, p3]) # 创建3D画布 fig = plt.figure(figsize=(12, 8), dpi=150) ax = fig.add_subplot(projection='3d') # 定义Z轴位置(对应8个传感器)和X轴偏移(避免同类重叠) z_positions = np.arange(8) x_offsets = np.array([-0.3, 0, 0.3]) # 遍历每个传感器绘制小提琴图 for z_idx, (z, data) in enumerate(zip(z_positions, sensor_data)): for x_idx, (x_off, class_data) in enumerate(zip(x_offsets, data)): # 绘制2D小提琴图 violin = sns.violinplot(x=[x_off]*len(class_data), y=class_data, ax=ax, color=f'C{x_idx}', alpha=0.7, width=0.25) # 将2D路径转换为3Z轴对应高度 for path in violin.collections: path._paths = [path._paths[0].transformed( ax.transData + plt.Affine2D().translate(0, 0, z) )] ax.clear() # 清除临时轴元素,避免重复 # 设置3D轴标签与刻度 ax.set_xlabel('类别') ax.set_xticks([0]) ax.set_xticklabels(['P1', 'P2', 'P3']) ax.set_ylabel('幅值 (V) x$10^4$') ax.set_zlabel('传感器编号') ax.set_zticks(z_positions) ax.set_zticklabels([f'传感器{i+1}' for i in range(8)]) ax.set_ylim([-3.8, 3.8]) # 添加图例 from matplotlib.patches import Patch legend_elements = [Patch(facecolor=f'C{i}', alpha=0.7, label=f'P{i+1}') for i in range(3)] ax.legend(handles=legend_elements, loc='upper right') plt.tight_layout() plt.show()
关键细节
- Z轴空间映射:通过
plt.Affine2D().translate()将2D小提琴图的路径坐标转换到3D空间的对应Z高度,实现堆叠。 - X轴偏移处理:给每类数据添加小幅度X偏移,避免同一传感器下的三个小提琴图重叠。
- 透明度优化:设置
alpha=0.7让后方图形部分可见,增强3D层次感。
内容的提问来源于stack exchange,提问作者dr_hesp
相关产品推荐
相关产品推荐

