You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib中调整多Y轴spine与图例的左侧布局

多独立Y轴Matplotlib布局解决方案

核心思路

通过创建多个共享X轴的独立Axes对象,手动调整每个轴的脊柱(spine)位置和图例偏移,实现你需要的【温度+湿度(左)---绘图区---气压+紫外线(右)】布局,完全适配独立数据。

完整实现代码

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# 构造示例数据(替换成你的真实数据)
dates = pd.date_range(start='2024-01-01', periods=20, freq='D')
temp = np.random.randint(10, 30, size=20)
humidity = np.random.randint(40, 80, size=20)
pressure = np.random.randint(1000, 1030, size=20)
uv = np.random.randint(0, 10, size=20)

# 创建画布和主X轴(用于共享日期轴)
fig, ax_main = plt.subplots(figsize=(12, 6))

# ---------------------- 左侧第一个Y轴:温度 ----------------------
ax_temp = ax_main.twinx()
# 将脊柱向左偏移15%绘图区宽度
ax_temp.spines['left'].set_position(('axes', -0.15))
ax_temp.spines['left'].set_visible(True)
ax_temp.spines['right'].set_visible(False)
# 刻度显示在左侧
ax_temp.yaxis.set_ticks_position('left')
# 绘制曲线并保存句柄用于图例
line_temp, = ax_temp.plot(dates, temp, color='#ff4444', label='温度(℃)')
# 把图例定位到脊柱左侧
ax_temp.legend(handles=[line_temp], loc='upper left', bbox_to_anchor=(-0.14, 1))

# ---------------------- 左侧第二个Y轴:湿度 ----------------------
ax_humidity = ax_main.twinx()
# 脊柱再向左偏移13%(累计偏移28%)
ax_humidity.spines['left'].set_position(('axes', -0.28))
ax_humidity.spines['left'].set_visible(True)
ax_humidity.spines['right'].set_visible(False)
ax_humidity.yaxis.set_ticks_position('left')
line_humidity, = ax_humidity.plot(dates, humidity, color='#33b5e5', label='湿度(%)')
ax_humidity.legend(handles=[line_humidity], loc='upper left', bbox_to_anchor=(-0.27, 0.9))

# ---------------------- 右侧第一个Y轴:气压 ----------------------
ax_pressure = ax_main.twinx()
# 脊柱向右偏移10%绘图区宽度
ax_pressure.spines['right'].set_position(('axes', 1.1))
ax_pressure.spines['right'].set_visible(True)
ax_pressure.spines['left'].set_visible(False)
ax_pressure.yaxis.set_ticks_position('right')
line_pressure, = ax_pressure.plot(dates, pressure, color='#99cc00', label='气压(hPa)')
ax_pressure.legend(handles=[line_pressure], loc='upper right', bbox_to_anchor=(1.09, 1))

# ---------------------- 右侧第二个Y轴:紫外线 ----------------------
ax_uv = ax_main.twinx()
# 脊柱再向右偏移13%(累计偏移23%)
ax_uv.spines['right'].set_position(('axes', 1.23))
ax_uv.spines['right'].set_visible(True)
ax_uv.spines['left'].set_visible(False)
ax_uv.yaxis.set_ticks_position('right')
line_uv, = ax_uv.plot(dates, uv, color='#ffbb33', label='紫外线指数')
ax_uv.legend(handles=[line_uv], loc='upper right', bbox_to_anchor=(1.22, 0.9))

# ---------------------- 整体布局调整 ----------------------
ax_main.set_xlabel('日期')
# 调整X轴刻度密度,避免重叠
ax_main.set_xticks(dates[::2])
ax_main.set_xticklabels(dates.strftime('%m-%d')[::2], rotation=45)
# 隐藏主轴的Y轴元素,消除干扰
ax_main.spines[['left', 'right']].set_visible(False)
ax_main.yaxis.set_visible(False)

# 调整画布左右边距,防止左侧轴/图例被截断
plt.subplots_adjust(left=0.2, right=0.8)
plt.tight_layout()
plt.show()

关键问题解决说明

  1. 脊柱位置调整失败:

    • 必须隐藏每个轴不需要的脊柱(比如温度轴隐藏右侧脊柱),否则偏移后会出现双重脊柱
    • set_position(('axes', offset))的offset是相对绘图区的比例,负数向左偏移,正数向右偏移
  2. 图例移到脊柱左侧/右侧:

    • 不能仅靠loc参数,需要配合bbox_to_anchor手动定位,数值和脊柱偏移量对应,保证图例和脊柱对齐
  3. 独立数据适配:

    • 每个指标用单独的twinx()创建轴,完全独立处理数据,避免secondary_yaxis只能基于主轴数据转换的限制

内容的提问来源于stack exchange,提问作者Ben Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:23:23