在Matplotlib中单个窗口显示多个3D柱状图避免变形
解决Matplotlib多3D柱状图视角与缩放不一致的问题
嘿,我看你在同一个窗口里放置多个3D柱状图时遇到了变形问题——各个图表的视角角度和缩放比例不统一,对吧?这在Matplotlib的3D绘图里其实是个挺常见的小坑,我来给你捋捋怎么解决。
问题根源
Matplotlib默认会为每个Axes3D实例单独计算视角参数(仰角、方位角)和坐标轴缩放范围,所以多个子图很容易出现“各玩各的”的情况,导致视觉上不协调。
解决方案:统一视角与缩放
核心思路是:先绘制一个基准子图,获取它的视角和坐标轴范围参数,然后把这些参数直接应用到其他所有子图上,确保所有图表的展示状态完全一致。
修改后的完整代码示例
from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import numpy as np # 补全你的数据(假设完整数据如下) cols = ['Seller', 'Section', 'Store', 'Total Pieces: Jan', 'Total Pieces: Feb'] mainList = [ ['BonM', 'Butterfly', 'E-shop', '5250', '1400'], ['BonM', 'Butterfly', 'FL Store', '3100', '2200'], ['BonM', 'Rose', 'E-shop', '4500', '1800'], ['BonM', 'Rose', 'FL Store', '2800', '2500'] ] # 将数值列转换为整数类型 data = np.array(mainList) jan_pieces = data[:, 3].astype(int) feb_pieces = data[:, 4].astype(int) categories = data[:, :3] # 创建画布和子图布局(这里用1行2列的布局示例) fig = plt.figure(figsize=(14, 7)) # 绘制第一个基准子图(一月数据) ax1 = fig.add_subplot(121, projection='3d') x_coords = np.arange(len(categories)) y_coords = np.zeros(len(categories)) z_coords = np.zeros(len(categories)) bar_width = bar_depth = 0.5 ax1.bar3d(x_coords, y_coords, z_coords, bar_width, bar_depth, jan_pieces) ax1.set_xlabel('Category') ax1.set_ylabel('Dummy Axis') ax1.set_zlabel('Total Pieces') ax1.set_title('January Sales') # 设置x轴刻度为分类名称(换行显示更清晰) ax1.set_xticks(x_coords + bar_width/2) ax1.set_xticklabels(['\n'.join(cat) for cat in categories]) # 获取基准子图的关键参数:视角(仰角、方位角)和z轴范围 base_elev = ax1.elev base_azim = ax1.azim z_min, z_max = ax1.get_zlim() # 绘制第二个子图(二月数据)并应用统一参数 ax2 = fig.add_subplot(122, projection='3d') ax2.bar3d(x_coords, y_coords, z_coords, bar_width, bar_depth, feb_pieces) ax2.set_xlabel('Category') ax2.set_ylabel('Dummy Axis') ax2.set_zlabel('Total Pieces') ax2.set_title('February Sales') ax2.set_xticks(x_coords + bar_width/2) ax2.set_xticklabels(['\n'.join(cat) for cat in categories]) # 应用统一视角和z轴范围 ax2.view_init(elev=base_elev, azim=base_azim) ax2.set_zlim(z_min, z_max) plt.tight_layout() plt.show()
关键细节说明
- 视角同步:通过
view_init()方法把基准图的elev(仰角)和azim(方位角)参数复制给其他子图,确保所有图表的观察角度完全一致。 - 缩放同步:通过
set_zlim()统一所有子图的z轴范围,避免因数据差异导致的缩放比例不同。 - 自定义视角:如果你想手动调整到一个更合适的视角,可以先运行代码,拖动第一个子图到满意的角度,然后打印
ax1.elev和ax1.azim的值,直接把数值写到view_init()里,这样所有子图都会固定用这个视角。
内容的提问来源于stack exchange,提问作者New2coding
相关产品推荐
相关产品推荐

