如何将FMSkill生成的多个预生成子图添加到同一matplotlib画布中
问题根源
你遇到的空白子图+独立窗口问题由两个错误导致:
- 调用
.plot_timeseries()时未指定目标坐标轴,该方法默认会自动创建新画布和新坐标轴完成绘图,因此每调用一次就会弹出一个独立窗口 - 执行顺序错误:你先调用了绘图方法生成独立窗口的图表,再往自定义画布添加空白子图,绘图内容从未渲染到你创建的子图上,自然子图全为空白。
正确实现方案
.plot_timeseries()方法原生支持ax入参,用于指定绘图的目标坐标轴。你只需要提前创建好整幅画布的所有子图坐标轴,遍历绘图时将对应位置的坐标轴传入方法即可,不需要做额外的图表迁移。
你原本的子图行列数计算逻辑可以简化,无需单独判断列表长度的奇偶性。
可直接运行的修正代码
import math import matplotlib.pyplot as plt import numpy as np import fmskill as fms n_plots = len(comparison) # 计算最优子图网格行列数 n_cols = int(math.ceil(np.sqrt(n_plots))) n_rows = int(math.ceil(n_plots / n_cols)) # 提前创建画布和所有子图坐标轴 fig, axes = plt.subplots(nrows=n_rows, ncols=n_cols, figsize=(n_cols*6, n_rows*4)) # 将坐标轴数组转为一维,兼容单行/单列子图的遍历场景 axes = axes.flatten() for idx, comp in enumerate(comparison): # 指定当前绘图渲染到对应位置的子图上 comp.plot_timeseries(ax=axes[idx]) # 隐藏网格中多余的空白子图(比如3张图用2*2网格时多出来的1个空位) for idx in range(n_plots, len(axes)): axes[idx].axis('off') # 自动调整子图间距,避免标签、标题重叠 plt.tight_layout() plt.show()
补充说明
- 原代码缺少
import matplotlib.pyplot as plt的导入,直接运行会触发名称错误,修正代码已补全 figsize参数可以根据自己的展示需求调整,上面的数值是按单图6*4英寸的比例自动计算总画布大小- 如果需要给每个子图加自定义标题、调整坐标轴范围,可以在
plot_timeseries调用后直接操作axes[idx]对象实现
内容的提问来源于stack exchange,提问作者VictorD
相关产品推荐
相关产品推荐

