如何为statsmodels的irf函数生成的画布添加等大无裁剪子图
解决方案
方案1:提取IRF绘图内容到自定义画布(推荐)
思路:既然irf.plot不支持传入自定义ax参数,我们可以先生成临时IRF画布,提取其绘图内容复制到预先创建的等分布局子图中,全程可控子图大小和间距,避免裁剪。
import matplotlib.pyplot as plt import pandas as pd # 第一步:预先创建2行1列、等大小的画布和子图 fig, (ax_custom, ax_irf) = plt.subplots(nrows=2, ncols=1, figsize=(8, 10), dpi=100) # 第二步:绘制自定义双轴折线图到第一个子图 df_clean = df[columns].dropna() ax_custom.plot(df_clean.index, df_clean.iloc[:, 1], color='red') ax_custom.tick_params(axis='y', labelcolor='red') ax_custom_twin = ax_custom.twinx() ax_custom_twin.plot(df_clean.index, df_clean.iloc[:, 0], color='blue') ax_custom_twin.tick_params(axis='y', labelcolor='blue') # 第三步:生成临时IRF图,提取内容到第二个子图 irf = results.irf() temp_fig = irf.plot(plot_stderr=False, impulse=columns[1], response=columns[0]) temp_ax = temp_fig.axes[0] # 复制IRF图的所有线条、样式到目标子图 for line in temp_ax.get_lines(): ax_irf.plot(line.get_xdata(), line.get_ydata(), color=line.get_color()) # 同步IRF图的坐标轴配置 ax_irf.set_xlabel(temp_ax.get_xlabel()) ax_irf.set_ylabel(temp_ax.get_ylabel()) ax_irf.set_title(temp_ax.get_title()) ax_irf.set_xlim(temp_ax.get_xlim()) ax_irf.set_ylim(temp_ax.get_ylim()) # 关闭临时画布释放内存 plt.close(temp_fig) # 调整布局避免裁剪 plt.subplots_adjust(hspace=0.3) fig.tight_layout() # 保存或显示结果 plt.savefig("combined_plot.png", bbox_inches='tight') plt.show()
方案2:分别绘图后合并为单张图片
思路:不需要修改原有绘图逻辑,分别生成两张独立图片后用PIL拼接为单张。
from PIL import Image import matplotlib.pyplot as plt # 1. 生成并保存自定义折线图 fig1, ax1 = plt.subplots(figsize=(8,5)) df_clean = df[columns].dropna() ax1.plot(df_clean.index, df_clean.iloc[:,1], color='red') ax1.tick_params(axis='y', labelcolor='red') ax2 = ax1.twinx() ax2.plot(df_clean.index, df_clean.iloc[:,0], color='blue') ax2.tick_params(axis='y', labelcolor='blue') plt.tight_layout() plt.savefig("custom_plot.png", bbox_inches='tight') plt.close() # 2. 生成并保存IRF图 irf = results.irf() fig_irf = irf.plot(plot_stderr=False, impulse=columns[1], response=columns[0]) fig_irf.set_size_inches(8,5) plt.tight_layout() plt.savefig("irf_plot.png", bbox_inches='tight') plt.close() # 3. 垂直拼接两张图片 img1 = Image.open("custom_plot.png") img2 = Image.open("irf_plot.png") combined_width = max(img1.width, img2.width) combined_height = img1.height + img2.height combined_img = Image.new('RGB', (combined_width, combined_height), (255,255,255)) combined_img.paste(img1, (0, 0)) combined_img.paste(img2, (0, img1.height)) combined_img.save("combined_final.png")
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

