Pandas/Matplotlib:不移动底部文本框时如何缩小其与图表的间距?
解决方案
问题核心是索引末尾的非规则日期导致Matplotlib自动为X轴预留了过多底部空间,同时手动设置的布局参数与自动布局逻辑冲突。以下是无需修改索引、无需格式化日期的解决方法:
方法一:使用约束布局(Constrained Layout)
约束布局会自动处理子图、标签和标题的间距,避免手动调整的冲突,同时可精准控制底部文本框位置:
import numpy as np import pandas as pd import matplotlib.pyplot as plt np.random.seed(0) no = 54 dates = pd.date_range("20090101", periods=no, freq="Q") df1 = pd.DataFrame(np.random.randn(no, 2), index=dates, columns=["Istanbul", "Kyiv"]) no = 1 dates = pd.date_range("20220826", periods=no) df2 = pd.DataFrame(np.random.randn(no, 2), index=dates, columns=["Istanbul", "Kyiv"]) df1 = pd.concat([df1,df2]) height = 8 # 启用自动约束布局,自动处理元素间距 fig, axes = plt.subplots(df1.shape[1], 1, figsize=(15, height), constrained_layout=True) fig.suptitle("Lorem ipsum dolor sit amet", y=1.02) # 微调标题位置避免被裁剪 # 绘制子图 for i, col in enumerate(df1.columns): df1.loc[:, col].plot(ax=axes[i], ylabel="(mm)", xlabel="", grid=True, legend=False, style=["o-"], sharex=True) axes[i].text(0.45, 0.87, f"{col}", transform=axes[i].transAxes, weight=600, bbox=dict(facecolor="white", ec="white"), fontsize=12) # 约束布局完成后添加数据源文本框,固定底部偏移 fig.text(0.1, 0.01, "Source: Lorem ipsum", fontsize=8) plt.show()
方法二:手动锁定X轴范围+调整布局参数
如果不想用约束布局,可手动锁定X轴范围(避免Matplotlib为非规则日期预留额外空间),再压缩底部间距:
import numpy as np import pandas as pd import matplotlib.pyplot as plt np.random.seed(0) no = 54 dates = pd.date_range("20090101", periods=no, freq="Q") df1 = pd.DataFrame(np.random.randn(no, 2), index=dates, columns=["Istanbul", "Kyiv"]) no = 1 dates = pd.date_range("20220826", periods=no) df2 = pd.DataFrame(np.random.randn(no, 2), index=dates, columns=["Istanbul", "Kyiv"]) df1 = pd.concat([df1,df2]) height = 8 fig, axes = plt.subplots(df1.shape[1], 1, figsize=(15, height)) fig.suptitle("Lorem ipsum dolor sit amet", y=1-0.2/height) fig.text(0.1, 0.01, "Source: Lorem ipsum", fontsize=8) # 绘制子图 for i, col in enumerate(df1.columns): df1.loc[:, col].plot(ax=axes[i], ylabel="(mm)", xlabel="", grid=True, legend=False, style=["o-"], sharex=True) axes[i].text(0.45, 0.87, f"{col}", transform=axes[i].transAxes, weight=600, bbox=dict(facecolor="white", ec="white"), fontsize=12) # 锁定X轴范围为数据实际起止日期,避免自动扩展 axes[-1].set_xlim(df1.index[0], df1.index[-1]) # 调整子图布局,缩小底部空白 fig.subplots_adjust( left=0.1, bottom=0.08, right=0.9, top=1-0.5/height, hspace=0.3 ) plt.show()
关键说明
- 方法一的
constrained_layout=True是最省心的方案,自动处理所有元素间距,无需手动计算布局参数。 - 方法二通过
set_xlim消除非规则日期导致的额外空间,再手动调整bottom参数压缩子图与文本框的间距。 - 两种方法均无需修改DataFrame索引或格式化日期,同时保留左右空白区域,文本框始终位于图表底部。
内容的提问来源于stack exchange,提问作者Alper
相关产品推荐
相关产品推荐

