如何将已创建的4个Matplotlib绘图整合为2×2网格图像?
解决Matplotlib已有绘图合并为2×2网格的问题
你遇到的问题很典型:ax.plot()方法是用来传入原始数据(比如x、y数组)绘制新线条的,而你传入的wshot_plot这类变量是已经绘制好的Axes或Figure对象,所以直接调用ax.plot()是不会生效的。下面给你三种可行的解决方案,按推荐程度排序:
方案一:复制已有Axes内容到新网格(推荐,保留矢量格式)
如果你的四个*shot_plot都是Matplotlib的Axes实例(比如用plt.plot()、Seaborn或Pandas绘图返回的对象),可以把旧Axes里的线条、标签、图例等元素复制到新的2×2子图中,这样能完全保留矢量图形的清晰度和可编辑性:
import matplotlib.pyplot as plt # 假设你已经有了四个Axes对象:wshot_plot, slshot_plot, snshot_plot, tshot_plot fig, axs = plt.subplots(2, 2, figsize=(10, 8)) # 按需调整画布大小 # 建立子图、旧绘图、标题的对应关系 plot_mapping = [ (axs[0, 0], wshot_plot, 'Wrist'), (axs[0, 1], slshot_plot, 'Slap'), (axs[1, 0], snshot_plot, 'Snap'), (axs[1, 1], tshot_plot, 'Tip-In') ] for new_ax, old_ax, title in plot_mapping: # 复制旧轴的所有线条、标记样式 for line in old_ax.get_lines(): new_ax.plot( line.get_xdata(), line.get_ydata(), color=line.get_color(), linestyle=line.get_linestyle(), marker=line.get_marker(), label=line.get_label() ) # 复制坐标轴标签 new_ax.set_xlabel(old_ax.get_xlabel()) new_ax.set_ylabel(old_ax.get_ylabel()) # 设置子图标题 new_ax.set_title(title) # 如果旧图有图例,同步添加 if old_ax.get_legend(): new_ax.legend() # 自动调整子图间距,避免标签重叠 plt.tight_layout() plt.show()
方案二:如果已有绘图是独立Figure对象
如果你的四个*shot_plot是单独的Figure实例(比如每个绘图都调用了plt.figure()创建新画布),可以把Figure渲染为图像后显示在子图中(注意:这种方法会把矢量图转为位图,清晰度会受影响):
import matplotlib.pyplot as plt import numpy as np # 假设四个plot都是独立的Figure对象 fig, axs = plt.subplots(2, 2, figsize=(10, 8)) plot_mapping = [ (axs[0, 0], wshot_plot, 'Wrist'), (axs[0, 1], slshot_plot, 'Slap'), (axs[1, 0], snshot_plot, 'Snap'), (axs[1, 1], tshot_plot, 'Tip-In') ] for new_ax, old_fig, title in plot_mapping: # 渲染旧Figure为图像数据 old_fig.canvas.draw() img_data = np.array(old_fig.canvas.renderer.buffer_rgba()) # 在新子图中显示图像 new_ax.imshow(img_data) # 隐藏子图的坐标轴(因为我们只是展示已有绘图) new_ax.axis('off') new_ax.set_title(title) plt.tight_layout() plt.show()
方案三:从一开始就用网格绘制(最高效)
如果还没完成四个绘图的创建,推荐直接在2×2网格的子图上分别绘制数据,这样就不需要事后合并了,代码更简洁:
import matplotlib.pyplot as plt # 直接创建2×2网格的画布和子图 fig, axs = plt.subplots(2, 2, figsize=(10, 8)) # 第一个子图:Wrist axs[0, 0].plot(x_wrist, y_wrist) # 替换成你的实际数据 axs[0, 0].set_title('Wrist') axs[0, 0].set_xlabel('X轴名称') axs[0, 0].set_ylabel('Y轴名称') # 第二个子图:Slap axs[0, 1].plot(x_slap, y_slap) axs[0, 1].set_title('Slap') axs[0, 1].set_xlabel('X轴名称') axs[0, 1].set_ylabel('Y轴名称') # 第三个子图:Snap axs[1, 0].plot(x_snap, y_snap) axs[1, 0].set_title('Snap') axs[1, 0].set_xlabel('X轴名称') axs[1, 0].set_ylabel('Y轴名称') # 第四个子图:Tip-In axs[1, 1].plot(x_tipin, y_tipin) axs[1, 1].set_title('Tip-In') axs[1, 1].set_xlabel('X轴名称') axs[1, 1].set_ylabel('Y轴名称') # 调整间距 plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Samuel DiSorbo
相关产品推荐
相关产品推荐

