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

Matplotlib绘图中图例与线条/符号匹配错误问题求助

Matplotlib图例与绘图元素不匹配的解决方法

问题说明

使用Matplotlib绘制包含线条、菱形/三角形标记的双图时,图例出现以下异常:

  • 最先绘制的线条和标记未在图例中显示
  • 图例末尾存在重复符号
  • 图例样式与实际绘图元素无法正确对应

原代码问题分析

原代码仅给最后一个plot调用添加了label参数,其余绘图元素均未指定label。当直接向plt.legend()传入labels列表时,Matplotlib只会收集带有label的绘图元素,导致标签列表和实际元素数量不匹配,最终出现图例混乱。

解决方案

方法1:为每个图例条目添加对应label

修改所有需要在图例中显示的plot调用,添加匹配的label参数,让Matplotlib自动关联元素与标签:

import numpy as np
from scipy.integrate import odeint
from scipy.io import loadmat
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(17, 7))
fig.subplots_adjust(wspace=.35)
ax1 = fig.add_subplot(1, 2, 1)

# 为模型线条和数据标记添加对应label
ax1.plot(t, np.sum(x[:, [5, 6, 7, 14, 16, 18]], axis=1), 'k', linewidth=line_wdth, label='Replicated viral DNA - Model')  # Total viral DNA
ax1.plot(np.concatenate([dataTotalDNA[:, 0], dataTotalDNA[:, 0], dataTotalDNA[:, 0]]),
         np.concatenate([dataTotalDNA[:, 1], dataTotalDNA[:, 2], dataTotalDNA[:, 3]]),
         'k^', linewidth=line_wdth, markersize=10, markerfacecolor='none', markeredgewidth=2,
         markeredgecolor='black', label='Replicated viral DNA - Data')
plt.xlabel(r'Time (hpt)', fontsize=ftsz)

if mode == 'manuscript':
    ax1.set_ylabel('AAV DNA copies/mL', fontsize=ftsz)
if mode == 'presentation':
    ax1.set_title('AAV DNA copies/mL', fontsize=ftsz)

ax1.set_xticks(range(0, 61, 12))
ax1.tick_params(labelsize=ftsz)

# 封装DNA的模型线条和数据标记添加label
ax1.plot(t, np.sum(x[:, [16, 18]], axis=1), 'r', linewidth=line_wdth, label='Full virion - Model')  # Encapsidated DNA
ax1.plot(np.concatenate([dataFullCap[:, 0], dataFullCap[:, 0], dataFullCap[:, 0]]),
         np.concatenate([dataFullCap[:, 1], dataFullCap[:, 2], dataFullCap[:, 3]]),
         'rs', linewidth=line_wdth, markersize=10, markerfacecolor='none', markeredgewidth=2, markeredgecolor='red', label='Full virion - Data')
ax1.plot([6, 6], [0, 7e9], 'k--', linewidth=1.2)  # Media exchange(无需图例)

ax1.set_ylim([0, 7e9])
ylim1 = ax1.get_ylim()
xlim1 = ax1.get_xlim()

if mode == 'manuscript':
    plt.text(-0.15 * xlim1[1], 1.01 * ylim1[1], r'A', fontsize=26, fontweight='bold')

# Total capsid vs full capsid
ax2 = fig.add_subplot(1, 2, 2)

# 总衣壳的模型线条和数据标记添加label
ax2.plot(t, np.sum(x[:, [15, 16, 17, 18]], axis=1), 'b', linewidth=line_wdth, label='Total capsid - Model')  # Total capsid
ax2.plot(dataCap[:, 0], dataCap[:, 1], 'bd', markersize=10, linewidth=line_wdth, markerfacecolor='none',
         markeredgewidth=2, markeredgecolor='blue', label='Total capsid - Data')

# 重复的Full capsid绘图无需再次添加label
ax2.plot(t, np.sum(x[:, [16, 18]], axis=1), 'r', linewidth=line_wdth)  # Full capsid
ax2.plot([dataFullCap[:, 0], dataFullCap[:, 0], dataFullCap[:, 0]],
         [dataFullCap[:, 1], dataFullCap[:, 2], dataFullCap[:, 3]],
         'rs', linewidth=line_wdth, markersize=10, markerfacecolor='none', markeredgewidth=2, markeredgecolor='red')

ax2.plot([6, 6], [0, 6e9], 'k--', linewidth=1.2)  # Media exchange(无需图例)
ax2.set_yscale('log')
ax2.set_ylim([1e8, 1e11])

ax2.set_xlim([0, 60])
ax2.set_xticks(range(0, 61, 12))
ax2.tick_params(labelsize=ftsz)

ax2.set_xlabel('Time (hpt)', fontsize=ftsz)
if mode == 'manuscript':
    ax2.set_ylabel('Capsids/mL (All Compartments)', fontsize=ftsz)
elif mode == 'presentation':
    ax2.set_title('Capsids/mL (All Compartments)', fontsize=ftsz)

ylim2 = ax2.get_ylim()
xlim2 = ax2.get_xlim()

if mode == 'manuscript':
    ax2.text(-0.22 * xlim2[1], 1.05 * ylim2[1], r'B', fontsize=26, fontweight='bold')

# 直接调用legend,无需手动传入labels列表
leg2 = plt.legend(loc='upper left', bbox_to_anchor=(-0.93, 1.127), ncol=3, fontsize=13)

plt.show()

方法2:手动构建自定义图例元素

如果不想修改原有绘图代码,可以通过Line2D手动创建图例条目,确保样式与绘图元素完全一致:

import numpy as np
from scipy.integrate import odeint
from scipy.io import loadmat
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

# 原绘图代码保持不变,仅替换图例部分
# ...(此处省略原绘图代码)

# 手动定义每个图例条目对应的样式
custom_legend = [
    Line2D([0], [0], marker='^', color='k', linestyle='', markerfacecolor='none', markeredgewidth=2, markersize=10),
    Line2D([0], [0], color='k', linewidth=line_wdth),
    Line2D([0], [0], marker='s', color='r', linestyle='', markerfacecolor='none', markeredgewidth=2, markersize=10),
    Line2D([0], [0], color='r', linewidth=line_wdth),
    Line2D([0], [0], marker='d', color='b', linestyle='', markerfacecolor='none', markeredgewidth=2, markersize=10),
    Line2D([0], [0], color='b', linewidth=line_wdth),
]

labels = ['Replicated viral DNA - Data', 'Replicated viral DNA - Model',
          'Full virion - Data', 'Full virion - Model',
          'Total capsid - Data', 'Total capsid - Model']

# 传入自定义图例元素和标签
leg2 = plt.legend(handles=custom_legend, labels=labels, loc='upper left', bbox_to_anchor=(-0.93, 1.127), ncol=3, fontsize=13)

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:03:15