如何将两个Matplotlib轴合并为单个轴(保留已有内容)
问题
现有两个通过以下代码创建的Matplotlib轴对象ax1和ax2:
xx = np.arange(12) fig1, ax1 = plt.subplots() ax1.plot(xx, np.sin(xx), label="V1") fig2, ax2 = plt.subplots() ax2.plot(xx, 0*xx, label="V2")
当前无法获取绘图代码,仅能访问fig1、ax1、fig2、ax2对象(例如通过pickle加载)。需要将ax1的线条复制到已有内容的ax2中,使合并后的轴视觉效果等同于直接在同一轴绘制两条线:
fig, ax = plt.subplots() ax.plot(xx, np.sin(xx), label="V1") ax.plot(xx, 0*xx, label="V2")
尝试了如下移动线条的代码但出现缩放错误:
# move lines from ax1 to ax2 def move_lines_to_axis(ax1, ax2): for line in ax1.lines: line.remove() line.set_linestyle("dashed") line.recache(always=True) ax2.add_line(line) return ax2 ax2 = move_lines_to_axis(ax1, ax2) ax2.figure
请问如何正确复制一个轴的线条到另一个已有轴中?
正确解决方案
之前的代码是移动线条而非复制,且直接移动线条会导致原轴的刻度范围等元数据未同步到新轴,从而出现缩放异常。正确的做法是复制线条的所有属性和数据,而非直接移动线条对象,具体实现如下:
完整复制代码
import matplotlib.pyplot as plt def copy_lines_to_axis(ax_source, ax_target): # 遍历源轴的所有线条,逐一复制到目标轴 for line in ax_source.lines: # 提取线条的x、y数据 xdata = line.get_xdata() ydata = line.get_ydata() # 提取线条的样式参数(保证视觉效果一致) style_props = { 'linestyle': line.get_linestyle(), 'color': line.get_color(), 'linewidth': line.get_linewidth(), 'marker': line.get_marker(), 'markersize': line.get_markersize(), 'label': line.get_label() } # 在目标轴绘制复制的线条 ax_target.plot(xdata, ydata, **style_props) # 让目标轴重新计算数据范围,自动适配刻度 ax_target.relim() ax_target.autoscale_view() # 更新图例,合并原有标签与新复制的标签 handles, labels = ax_target.get_legend_handles_labels() ax_target.legend(handles, labels) return ax_target # 执行复制操作 ax2 = copy_lines_to_axis(ax1, ax2) # 显示合并后的图形 plt.show()
错误原因说明
- 直接移动线条对象时,线条仍保留与原轴的内部关联属性,导致目标轴无法正确识别新添加的数据范围,进而出现缩放异常
- 仅调用
line.recache()无法触发目标轴重新计算刻度,必须通过relim()和autoscale_view()强制目标轴适配所有数据
可选:移动线条而非复制
如果需要将线条从原轴完全转移到目标轴(原轴不再保留该线条),可以在复制完成后删除原轴的线条:
def move_lines_to_axis(ax_source, ax_target): # 先复制线条到目标轴 copy_lines_to_axis(ax_source, ax_target) # 移除原轴的所有线条 for line in list(ax_source.lines): line.remove() # 刷新原轴的显示 ax_source.figure.canvas.draw_idle() return ax_target
内容的提问来源于stack exchange,提问作者Maximilian Mordig
相关产品推荐
相关产品推荐

