如何使用Seaborn/Matplotlib单独调整单个子图的宽度
Matplotlib/Seaborn 单独调整单个子图宽度的实现方法
不需要重构复杂的网格结构,最简便的方案是直接修改目标子图的位置参数,全程只需要新增3行核心代码。
方案一:手动调整子图边界(最灵活)
Matplotlib 子图的位置用归一化坐标表示,格式为[左边界, 下边界, 宽度, 高度],取值范围0-1,对应相对于画布的比例。你只需要在绘制完所有元素、摆好第一个子图的外置图例后,直接拉宽第二个子图的右边界即可。
完整可运行代码:
import seaborn as sns import matplotlib.pyplot as plt fig, ax = plt.subplots(2,figsize=(20, 6),gridspec_kw={'height_ratios': [2,1]}) fmri = sns.load_dataset("fmri") flights = sns.load_dataset("flights") sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event", ax=ax[0]) ax[0].legend(bbox_to_anchor=(1.02, 1), loc=2, borderaxespad=0.) sns.lineplot(data=flights, x="year", y="passengers", ax=ax[1]) # 核心调整逻辑 pos0 = ax[0].get_position() pos1 = ax[1].get_position() # 0.92为第二个子图的右边界位置,可根据图例宽度自行微调,数值越大子图越宽 ax[1].set_position([pos1.x0, pos1.y0, 0.92 - pos1.x0, pos1.height]) fig.savefig("test.png")
默认运行效果:
调整后即可匹配目标效果:
方案二:优化GridSpec布局(无手动坐标调试)
如果不想手动微调边界数值,可以优化你之前尝试的GridSpec方案,不需要额外创建隐藏空轴,直接给第一行预留图例的宽度比例即可:
import seaborn as sns import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpec fig = plt.figure(figsize=(20, 6)) # 把网格拆成2行11列,第一行占前10列给绘图区,剩1列留位置给图例 gs = GridSpec(2, 11, height_ratios=[2,1]) ax = [ fig.add_subplot(gs[0, :10]), fig.add_subplot(gs[1, :]) # 第二行占满全部11列,自然比第一个子图宽 ] fmri = sns.load_dataset("fmri") flights = sns.load_dataset("flights") sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event", ax=ax[0]) ax[0].legend(bbox_to_anchor=(1.02, 1), loc=2, borderaxespad=0.) sns.lineplot(data=flights, x="year", y="passengers", ax=ax[1]) fig.savefig("test.png")
这个方案的缺点是宽度比例固定,如果后续调整图例大小,需要同步修改列数比例。
内容的提问来源于stack exchange,提问作者masaya
相关产品推荐
相关产品推荐

