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()
关键修改说明
- 解决图例重复&图例映射错误:
- 调整分组维度,移除
svIonoStdev,避免同一卫星因标准差不同被拆分成多个子组,导致重复绘制线条和图例。 - 用
legend_added字典跟踪已添加的图例,同一卫星仅首次绘制时设置label,后续绘制时设为None,确保每个图例只显示一次。
- 调整分组维度,移除
- 解决图例位置错误:
调用legend()时指定loc='upper right',将图例固定到右侧。 - 解决图像重叠:
调整分组维度后,同一卫星的所有数据点被合并为一组绘制,避免重复绘制同一卫星的线条造成重叠。 - 优化代码结构:
将轴属性设置(标题、标签、网格等)移到循环外,避免重复执行,提升代码效率。
内容的提问来源于stack exchange,提问作者Kapil
相关产品推荐
相关产品推荐

