如何在matplotlib中将箱线图等2D图表投影到3D空间展示
3D空间分层展示箱线图实现方法
问题原因
Matplotlib内置的boxplot接口未提供zs、zdir这类直接指定3D偏移位置的参数,所以不能像柱状图一样直接传参实现分层。
实现方案
我们可以在绘制完2D箱线图后,手动将箱线图的所有元素沿指定轴偏移到目标z位置,即可实现和示例一致的分层效果,完整可运行代码如下:
from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.mplot3d.art3d import line_2d_to_3d, pathpatch_2d_to_3d import numpy as np import matplotlib.pyplot as plt fig = plt.figure(figsize=(8,8)) ax = fig.add_subplot(111, projection='3d') # 分层位置、对应颜色配置,和原柱状图示例逻辑一致 z_positions = [30, 20, 10, 0] colors = ['r', 'g', 'b', 'y'] for z, c in zip(z_positions, colors): # 生成每组的随机测试数据,可替换为自己的数据集 data = [np.random.normal(loc=i*5, scale=3, size=500) for i in range(4)] # 先绘制2D箱线图,patch_artist设为True才能自定义箱体填充色 box = ax.boxplot(data, patch_artist=True, vert=True) # 遍历箱线图所有元素,转换为3D并设置偏移位置 # 转换箱体 for patch in box['boxes']: patch.set_facecolor(c) patch.set_alpha(0.8) pathpatch_2d_to_3d(patch, z=z, zdir='y') # 转换须线、帽线、中位数线 for line_list in [box['whiskers'], box['caps'], box['medians']]: for line in line_list: line.set_color(c) line_2d_to_3d(line, z=z, zdir='y') # 转换异常点 for flier in box['fliers']: flier.set_markeredgecolor(c) flier.set_alpha(0.8) # 散点单独处理z偏移 x, y = flier.get_data() ax.scatter(x, [z]*len(x), y, c=c, alpha=0.6, s=10) # 删掉原来的2D异常点,避免重复显示 for flier in box['fliers']: flier.remove() # 坐标轴设置和原示例保持一致 ax.set_xlabel('分组') ax.set_ylabel('Y(分层轴)') ax.set_zlabel('数值') # 限制Y轴范围避免显示问题 ax.set_ylim(-5, 35) plt.show()
关键说明
- 核心依赖
art3d模块提供的2D元素转3D接口,所有Matplotlib 2D图表都可以用类似思路实现3D分层投影 - 如需修改分层方向,把所有
zdir='y'改为zdir='x'即可沿X轴方向分层 - 如需替换为自己的数据集,直接替换循环内的
data变量即可,格式和普通2D箱线图的输入要求完全一致
内容的提问来源于stack exchange,提问作者Tomoon
相关产品推荐
相关产品推荐

