如何在Matplotlib的3D子图中移除黑色边框
如何移除Matplotlib中3D子图的黑色边框?
我有一段Matplotlib代码,能生成两个子图,但不管怎么设置参数,第二个3D子图的黑色边框就是去不掉,请问该怎么解决?
原代码如下:
import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D beta, gamma = np.linspace(-np.pi / 2, np.pi / 2, 500), np.linspace(-np.pi / 2, np.pi / 2, 500) B, G = np.meshgrid(beta, gamma) # 补充原代码缺失的obj_vals计算示例 obj_vals = np.sin(B) + np.cos(G) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6)) # 2D Contour plot ax1.imshow(obj_vals.T, origin='lower', cmap='hot', extent=(-np.pi/2, np.pi/2, -np.pi/2, np.pi/2)) ax1.set_xlabel(r'$\gamma$') ax1.set_ylabel(r'$\beta$') ax1.set_xticks([]) ax1.set_yticks([]) ax2 = fig.add_subplot(122, projection='3d') # Make panes transparent ax2.xaxis.pane.fill = False # Left pane ax2.yaxis.pane.fill = False # Right pane ax2.zaxis.pane.fill = False # Right pane # Remove grid lines ax2.grid(False) # Remove tick labels ax2.set_xticklabels([]) ax2.set_yticklabels([]) ax2.set_zticklabels([]) # Transparent spines ax2.xaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax2.yaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax2.zaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax2.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax2.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) # No ticks ax2.set_xticks([]) ax2.set_yticks([]) ax2.set_zticks([]) # Surface plot surf = ax2.plot_surface(B, G, obj_vals.T, cmap='hot') plt.axis('off') plt.tight_layout() plt.show()
问题原因
你一开始用plt.subplots(1,2)创建了两个2D子图,之后又用fig.add_subplot(122, projection='3d')重新创建了一个3D子图并覆盖了变量ax2,但原来的2D子图并没有被删除,那个你看到的黑色边框其实是原来的2D子图的边框,不是3D子图的。
解决方法
有两种简单的修复方式:
方式一:直接创建带3D投影的子图
一开始就明确第二个子图是3D类型,避免重复创建:
import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D beta, gamma = np.linspace(-np.pi / 2, np.pi / 2, 500), np.linspace(-np.pi / 2, np.pi / 2, 500) B, G = np.meshgrid(beta, gamma) obj_vals = np.sin(B) + np.cos(G) # 直接指定第二个子图的projection为3d fig = plt.figure(figsize=(12, 6)) ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122, projection='3d') # 2D Contour plot ax1.imshow(obj_vals.T, origin='lower', cmap='hot', extent=(-np.pi/2, np.pi/2, -np.pi/2, np.pi/2)) ax1.set_xlabel(r'$\gamma$') ax1.set_ylabel(r'$\beta$') ax1.set_xticks([]) ax1.set_yticks([]) # 3D子图设置 # 隐藏面板填充 ax2.xaxis.pane.fill = False ax2.yaxis.pane.fill = False ax2.zaxis.pane.fill = False # 隐藏网格 ax2.grid(False) # 隐藏刻度和刻度标签 ax2.set_xticks([]) ax2.set_yticks([]) ax2.set_zticks([]) ax2.set_xticklabels([]) ax2.set_yticklabels([]) ax2.set_zticklabels([]) # 隐藏坐标轴 spine ax2.xaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax2.yaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax2.zaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) # 设置面板透明 ax2.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax2.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax2.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) # 绘制曲面 surf = ax2.plot_surface(B, G, obj_vals.T, cmap='hot') plt.tight_layout() plt.show()
方式二:删除原来的2D子图
如果你不想改动初始的subplots代码,可以在创建3D子图前先删除原来的ax2:
# 在原代码的ax2 = fig.add_subplot(...)之前添加这行: fig.delaxes(ax2) ax2 = fig.add_subplot(122, projection='3d')
关键修改点总结
- 避免重复创建子图,确保每个位置只有一个子图存在
- 针对3D子图,不仅要隐藏刻度、网格,还要确保没有残留的2D子图边框
内容的提问来源于stack exchange,提问作者Vivek Katial
相关产品推荐
相关产品推荐

