You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:20:34