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

Matplotlib子图偏移图像消失问题及解决方案咨询

解决host_subplot中AnnotationBbox图像偏移后消失的问题

问题原因

AnnotationBbox默认受**轴裁剪(clipping)**限制,超出轴显示区域的部分会被隐藏;当子图布局为111时,子图占满整个画布,偏移到边缘的图像会被画布边界切掉,plt.tight_layout()仅调整子图间间距,无法解决这类主动偏移元素的显示问题。

核心解决方案

  1. 关闭AnnotationBbox的裁剪功能,让元素不受轴范围限制显示
  2. 调整画布边距,给偏移的图像留出足够显示空间

代码示例(单图像+多y轴)

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import host_subplot
from matplotlib.offsetbox import AnnotationBbox, OffsetImage
import numpy as np

# 创建画布与host子图(111布局)
fig = plt.figure(figsize=(10, 6))
host = host_subplot(111)

# 绘制主曲线
x = np.linspace(0, 10, 100)
host.plot(x, np.sin(x), label='主传感器数据')

# 添加第二个y轴及曲线
par1 = host.twinx()
par1.plot(x, np.cos(x)*10, 'r', label='辅助传感器数据')

# 准备示例图像(实际使用替换为你的传感器图例图像)
sensor_img = np.random.rand(50, 50)  # 可替换为 plt.imread("sensor_icon.png")
img_box = OffsetImage(sensor_img, zoom=0.5)

# 创建AnnotationBbox,关键设置clip_on=False关闭裁剪
anno_box = AnnotationBbox(
    img_box, (-0.5, 0),  # 偏移位置
    xycoords='data',
    boxcoords="offset points",
    pad=0.1,
    clip_on=False  # 关闭裁剪,让图像超出轴范围也能显示
)

host.add_artist(anno_box)

# 调整画布左边距,给偏移的图像留出空间
plt.subplots_adjust(left=0.2)

# 设置图例与显示
host.legend(loc='upper right')
plt.show()

批量添加传感器图例(适配30个传感器场景)

如果需要批量添加多个传感器图像并连接到对应曲线,用轴比例坐标布局更稳定,不受数据范围影响:

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import host_subplot
from matplotlib.offsetbox import AnnotationBbox, OffsetImage
import numpy as np

fig = plt.figure(figsize=(12, 8))
host = host_subplot(111)

x = np.linspace(0, 10, 100)
sensor_count = 30  # 实际传感器数量
colors = plt.cm.tab20(np.linspace(0, 1, sensor_count))

# 批量绘制传感器曲线
for idx in range(sensor_count):
    host.plot(x, np.sin(x + idx/5), color=colors[idx], label=f'传感器{idx+1}')

# 调整左边距,足够容纳所有图例图像
plt.subplots_adjust(left=0.35)

# 批量添加图像图例+连线
for idx in range(sensor_count):
    # 生成带对应曲线颜色的示例图像(替换为你的传感器图标)
    sensor_img = np.full((30, 30, 3), colors[idx][:3])
    img_box = OffsetImage(sensor_img, zoom=0.35)
    
    # 用轴比例坐标定位,垂直排列图像
    anno_box = AnnotationBbox(
        img_box, (-0.9, 0.02 + idx*0.032),
        xycoords='axes fraction',  # 基于轴的比例定位,不受数据范围影响
        boxcoords="offset points",
        pad=0.1,
        clip_on=False
    )
    host.add_artist(anno_box)
    
    # 添加连线,连接图像与对应曲线的起点
    host.annotate(
        '',
        xy=(x[0], np.sin(x[0] + idx/5)),  # 曲线起点坐标
        xycoords='data',
        xytext=(0, 0.02 + idx*0.032),  # 图像对应的轴比例坐标
        textcoords='axes fraction',
        arrowprops={'arrowstyle': '-', 'color': colors[idx], 'linewidth': 1.2}
    )

# 调整图例位置,避免遮挡
host.legend(loc='upper right', bbox_to_anchor=(1.2, 1))
plt.show()

关键参数说明

  • clip_on=False:强制关闭AnnotationBbox的裁剪,是图像超出轴范围仍显示的核心设置
  • plt.subplots_adjust(left=xxx):根据图像偏移距离和大小调整画布边距,确保图像不会被画布边界切掉
  • xycoords='axes fraction':使用轴的比例坐标(0-1范围)定位图像,适合批量排列元素,不受数据轴范围变化影响

内容的提问来源于stack exchange,提问作者Thomas Lewis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 19:57:22