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

Matplotlib绘图异常求助:图例错误、图像重叠等问题

解决Matplotlib绘图的四个问题:重复图例、位置错误、图例映射错误、图像重叠

问题描述

我正在绘制svIonoStdev与iTOW的关系图,需筛选sourceId为0和1的数据,并按svGnssId和svSvId分组。目前已实现分组,但遇到以下绘图问题:

  • 图例重复
  • 图例显示在左侧而非预期的右侧
  • 不同数值和颜色对应相同的图例值
  • 图像重叠

测试代码

import matplotlib.pyplot as plt
import pandas as pd

new_msg_dict = {
    'sourceId': [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0],
    'iTOW': [518490.0, 518490.0, 518490.0, 518490.0, 518490.0, 518490.0, 518490.0, 518492.0, 518492.0, 518492.0, 518492.0, 518492.0, 518492.0, 518492.0, 518493.0, 518493.0],
    'svGnssId': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
    'svSvId': [1.0, 10.0, 14.0, 21.0, 22.0, 27.0, 32.0, 1.0, 10.0, 14.0, 21.0, 22.0, 27.0, 32.0, 1.0, 10.0],
    'ionoCorr': [-0.14, 0.034, 1.973, -1.09, 7.136, 4.187, 2.006, -0.14, 0.034, 1.973, -1.09, 7.136, 4.187, 2.0060000000000002, -0.14, 0.034],
    'svIonoStdev': [0.03, 0.03, 0.05, 0.03, 0.05, 0.03, 0.03, 0.03, 0.03, 0.05, 0.03, 0.05, 0.03, 0.03, 0.03, 0.03]
}
new_msg_df = pd.DataFrame(new_msg_dict)
satellite = 'GPS'

new_gk_stddev = list(new_msg_df.groupby(['svGnssId', 'svSvId', 'sourceId', 'svIonoStdev']))
fig, ax = plt.subplots(2, constrained_layout=True)
for i in new_gk_stddev:
    if i[0][2] == 1.0:
        ax[0].plot(i[1]['iTOW'], i[1]['svIonoStdev'], label=f"{satellite} {i[0][1]}")
        ax[0].set_ylabel("Standard deviation (TECU)")
        ax[0].set_xlabel("Itows (mSec)")
        ax[0].grid(True)
        ax[0].legend(fontsize=4)
        ax[0].set_title('Correction Handler Output')
    elif i[0][2] == 2.0:
        ax[1].plot(i[1]['iTOW'], i[1]['svIonoStdev'], label=f"{satellite} {i[0][1]}")
        ax[1].set_ylabel("Standard deviation (TECU)")
        ax[1].set_xlabel("Itows (mSec)")
        ax[1].grid(True)
        ax[1].legend(fontsize=4)
        ax[1].set_ylim([0, 0.05])
        ax[1].set_title('HPG Filter Output')

解决方案及修正代码

import matplotlib.pyplot as plt
import pandas as pd

new_msg_dict = {
    'sourceId': [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0],
    'iTOW': [518490.0, 518490.0, 518490.0, 518490.0, 518490.0, 518490.0, 518490.0, 518492.0, 518492.0, 518492.0, 518492.0, 518492.0, 518492.0, 518492.0, 518493.0, 518493.0],
    'svGnssId': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
    'svSvId': [1.0, 10.0, 14.0, 21.0, 22.0, 27.0, 32.0, 1.0, 10.0, 14.0, 21.0, 22.0, 27.0, 32.0, 1.0, 10.0],
    'ionoCorr': [-0.14, 0.034, 1.973, -1.09, 7.136, 4.187, 2.006, -0.14, 0.034, 1.973, -1.09, 7.136, 4.187, 2.0060000000000002, -0.14, 0.034],
    'svIonoStdev': [0.03, 0.03, 0.05, 0.03, 0.05, 0.03, 0.03, 0.03, 0.03, 0.05, 0.03, 0.05, 0.03, 0.03, 0.03, 0.03]
}
new_msg_df = pd.DataFrame(new_msg_dict)
satellite = 'GPS'

# 调整分组维度:移除svIonoStdev,避免同一卫星被拆分为多组
grouped = new_msg_df.groupby(['svGnssId', 'svSvId', 'sourceId'])

fig, ax = plt.subplots(2, constrained_layout=True)
# 用字典记录已添加的图例,避免重复
legend_added = {0: set(), 1: set()}

for (gnss_id, sv_id, source_id), data in grouped:
    if source_id == 1.0:
        current_ax = ax[0]
        legend_key = f"{satellite} {sv_id}"
        # 仅首次绘制时设置图例标签
        label = legend_key if legend_key not in legend_added[0] else None
        current_ax.plot(data['iTOW'], data['svIonoStdev'], label=label)
        if label is not None:
            legend_added[0].add(legend_key)
    elif source_id == 2.0:
        current_ax = ax[1]
        legend_key = f"{satellite} {sv_id}"
        label = legend_key if legend_key not in legend_added[1] else None
        current_ax.plot(data['iTOW'], data['svIonoStdev'], label=label)
        if label is not None:
            legend_added[1].add(legend_key)

# 统一设置轴属性,避免循环内重复执行
ax[0].set_ylabel("Standard deviation (TECU)")
ax[0].set_xlabel("Itows (mSec)")
ax[0].grid(True)
# 设置图例到右侧
ax[0].legend(fontsize=4, loc='upper right')
ax[0].set_title('Correction Handler Output')

ax[1].set_ylabel("Standard deviation (TECU)")
ax[1].set_xlabel("Itows (mSec)")
ax[1].grid(True)
ax[1].legend(fontsize=4, loc='upper right')
ax[1].set_ylim([0, 0.05])
ax[1].set_title('HPG Filter Output')

plt.show()

关键修改说明

  • 解决图例重复&图例映射错误:
    1. 调整分组维度,移除svIonoStdev,避免同一卫星因标准差不同被拆分成多个子组,导致重复绘制线条和图例。
    2. 用legend_added字典跟踪已添加的图例,同一卫星仅首次绘制时设置label,后续绘制时设为None,确保每个图例只显示一次。
  • 解决图例位置错误:
    调用legend()时指定loc='upper right',将图例固定到右侧。
  • 解决图像重叠:
    调整分组维度后,同一卫星的所有数据点被合并为一组绘制,避免重复绘制同一卫星的线条造成重叠。
  • 优化代码结构:
    将轴属性设置(标题、标签、网格等)移到循环外,避免重复执行,提升代码效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 04:15:21