作为一名工程师或研究人员,我们经常需要在 MATLAB 中绘制复杂的数据曲线。一张没有图例的图表,就像一本没有目录的书籍,观者很难快速理解数据的含义。但在 2026 年,随着数据规模的爆炸式增长和开发工具的智能化,我们对图表可视化的要求早已超越了“能够看懂”的层面——我们需要的是出版级的精度、自动化的工作流以及能够适应云端协作的鲁棒性。
在这篇文章中,我们将深入探讨 MATLAB 中 legend 函数的强大功能。我们将一起学习如何为基础图形添加图例,如何处理多坐标轴图例,以及如何通过精细调整让我们的图表达到专业水准。更重要的是,我们将结合当下的 AI 辅助编程趋势,分享如何构建高可维护性的可视化代码。
为什么图例在数据可视化中至关重要
在开始编写代码之前,让我们先达成一个共识:图例不仅仅是一个装饰,它是数据可视化的关键组件。当我们需要在同一个坐标系中展示多条曲线时,图例赋予了每一条线独特的身份。在 MATLAB 中,legend 函数非常智能,它能自动捕捉我们绘图时的数据标签,并将其整齐地展示出来。但在现代开发工作流中,图例更是数据故事讲述者的核心工具。一个精心设计的图例,能够瞬间引导观众的注意力聚焦在关键数据上,而不是让他们迷失在色彩斑斓的线条迷宫中。
基础入门:为单条和多条曲线添加图例
让我们从最基础的使用场景开始。在 MATLAB 中,添加图例的标准流程是:先使用 INLINECODE521cbe3e 函数绘制数据,然后立即调用 INLINECODEf81cef8f 函数。这一过程虽然简单,但在 2026 年的代码规范中,我们更强调语法的清晰度和可预测性。
#### 示例 1:基础的正弦与余弦图例
这是最经典的入门示例。我们将绘制正弦和余弦两条曲线,并赋予它们人类可读的标签。
% 定义 x 轴范围:从 -pi 到 pi,生成 1000 个点
rng = linspace(-pi, pi, 1000);
% 绘制正弦曲线
% 注意:这里没有指定变量句柄,MATLAB 会自动管理
plot(rng, sin(rng))
% 保持当前图像,以便在同一坐标轴上绘制余弦曲线
hold on
% 绘制余弦曲线
plot(rng, cos(rng))
% 添加图例
% MATLAB 会按照 plot 的执行顺序,依次将 ‘Sine‘ 匹配给第一条线,‘Cosine‘ 匹配给第二条线
legend(‘Sine‘, ‘Cosine‘)
代码解读: 在这个例子中,我们使用了字符串直接作为参数。你需要注意标签的顺序必须与绘图顺序严格一致。如果顺序颠倒,图例就会产生误导,这是初学者最容易犯的错误之一。而在 2026 年的自动化脚本中,依赖隐式顺序往往是不安全的,我们更倾向于显式绑定。
#### 示例 2:使用元胞数组批量管理图例
当我们需要绘制大量曲线,或者标签内容较长时,直接在函数调用中写一长串字符串并不是最佳实践。为了保持代码的整洁和可维护性,我们可以使用元胞数组来存储标签。
% 重新定义范围
rng = linspace(-pi, pi, 1000);
% 绘制 sin^2 曲线
plot(rng, sin(rng).^2)
hold on
% 绘制 cos^2 曲线
plot(rng, cos(rng).^2)
% 创建字符向量数组
lgd = {‘sine squared‘, ‘cosine squared‘};
% 将数组转换为元胞数组
% 虽然在 modern MATLAB 中 {} 直接定义即为元胞数组,但显式转换可以增加代码的健壮性
lgd = cell(lgd);
% 传递元胞数组给 legend 函数
legend(lgd)
实用见解: 这种方法的优点在于,你可以提前在脚本的开头定义所有的标签变量。当你需要修改标签名称或进行国际化处理时,只需要修改元胞数组的内容,而不需要深入到代码逻辑中去寻找 legend 函数的调用位置。这种数据与逻辑分离的思想,是现代软件工程的基础。
2026 开发视角:企业级图例管理的最佳实践
在我们最近的一个大型仿真项目中,我们需要生成超过 500 个参数化图表。如果还在手动硬编码 ‘Sine‘, ‘Cosine‘ 这样的字符串,维护成本将是灾难性的。随着 Agentic AI(自主代理)和结对编程的普及,代码的可读性和结构化变得前所未有的重要。我们必须采用一种能让 AI 辅助工具(如 GitHub Copilot 或 Cursor)轻松理解的写法。
#### 示例 3:使用 DisplayName 属性解耦绘图与图例
这是目前最推荐的“现代化”写法。通过在绘图时直接赋予对象身份,我们彻底避免了图例顺序错误的风险。
% 定义数据
x = linspace(0, 10, 100);
% 绘图时直接指定 ‘DisplayName‘
% 这样我们在后续添加图例时,不需要关心绘图顺序,也不需要传入字符串数组
plot(x, sin(x), ‘DisplayName‘, ‘Sine Wave‘, ‘LineWidth‘, 1.5); hold on;
plot(x, cos(x), ‘DisplayName‘, ‘Cosine Wave‘, ‘LineWidth‘, 1.5);
% 直接调用 legend show,它会自动收集所有带有 DisplayName 的图形对象
% 这种写法在需要动态增删曲线时极其稳健
lgd = legend(‘show‘);
% 设定位置
lgd.Location = ‘best‘;
专家提示: 这种写法是“防御性编程”的体现。即使你在代码中插入了几条不需要显示在图例中的辅助线(只要不设置 DisplayName),它们就不会干扰最终的图例生成。这对于复杂的模块化程序至关重要。
进阶技巧:多坐标系与复杂布局
在实际的工程应用中,我们经常需要在一个图形窗口中展示多个子图。这时候,如何精确地为每个子图添加独立的图例就成了一个挑战。
#### 示例 4:在同一窗口中为不同坐标轴添加图例
当我们使用 INLINECODEf2f4eb85 或者手动创建 INLINECODE29ca84a5 时,必须明确指定我们要为哪一个坐标轴添加图例。依赖隐式的当前坐标轴(GCA)在多图脚本中极其危险。
% 定义数据范围
rng = linspace(-pi, pi, 1000);
% 创建第一个坐标轴 ax1,位置设定在窗口的左下角
% Position 向量:[x, y, width, height]
ax1 = axes(‘Position‘, [0.05 0.05 0.5 0.5]);
% 创建第二个坐标轴 ax2,位置设定在窗口的右上角
ax2 = axes(‘Position‘, [0.6 0.6 0.35 0.35]);
% 在 ax1 中绘图
plot(ax1, rng, sin(rng).^2)
title(ax1, ‘Axes 1: Sine Wave‘)
% 为 ax1 添加图例
% 这里关键在于第一个参数 ax1,它告诉 legend 函数要去修饰哪个对象
legend(ax1, ‘Sine‘)
% 在 ax2 中绘图
plot(ax2, rng, cos(rng).^2)
title(ax2, ‘Axes 2: Cosine Wave‘)
% 为 ax2 添加图例
legend(ax2, ‘Cosine‘)
核心要点: 请注意 INLINECODEf789addd 的语法。默认情况下,INLINECODEc957b7c1 作用于当前坐标轴(gca)。但在多图环境下,依赖“当前”概念是非常危险的,显式地传入坐标轴句柄是专业编程的最佳实践。
视觉优化:调整图例位置与样式
默认情况下,MATLAB 会尝试寻找一个“最佳”位置放置图例,以免遮挡数据。但算法并不完美,我们经常需要手动干预以达到出版级质量。
#### 示例 5:指定图例位置与方向
我们可以使用 INLINECODE90f63b24 参数将图例固定在特定的方位。特别是对于长标签,横向排列图例(INLINECODE81a62e52)往往比纵向更节省垂直空间。
% 准备数据
rng = linspace(-pi, pi, 1000);
% 绘制数据
plot(rng, sin(rng))
hold on
plot(rng, cos(rng))
hold off
% 准备图例标签
lgd = {‘Sine Function‘, ‘Cosine Function‘};
% 添加图例并设置位置
% ‘north‘ 表示将图例置于坐标轴的顶部中间
% ‘Orientation‘, ‘horizontal‘ 将图例横向排列,适合顶部放置
legend(lgd, ‘Location‘, ‘north‘, ‘Orientation‘, ‘horizontal‘)
#### 示例 6:自定义图例外观(实战进阶)
为了达到出版级的效果,我们通常还需要去除图例的边框,或者修改其透明度。让我们通过一个更高级的例子来演示如何获取图例句柄并修改其属性。
% 绘制图表
data = rand(10, 3);
plot(data, ‘LineWidth‘, 2)
% 添加图例并获取句柄
% 这里的 lgd 变量不再是一个字符串数组,而是一个 Legend 对象
lgd = legend({‘Set A‘, ‘Set B‘, ‘Set C‘});
% --- 开始美化 ---
% 1. 设置图例位置
lgd.Location = ‘best‘;
% 2. 设置图例的字体大小和字体名称
% 在 2026 年的论文投稿中,字体一致性至关重要
lgd.FontSize = 12;
lgd.FontName = ‘Arial‘;
% 3. 去除图例的背景框(使其透明)
% 这在需要将图例覆盖在网格线上时非常有用
lgd.Box = ‘off‘;
% 4. 修改图例文本的颜色
lgd.TextColor = [0.2, 0.2, 0.2]; % 深灰色
专家提示: 当你在制作复杂的矢量图用于论文发表时,建议将 INLINECODEe6e79394 设置为 INLINECODE83a49100,这样图例不会显得突兀,且能更好地与背景融合。
深度探索:交互式图例与大数据性能优化
在 2026 年的工程环境中,静态图表往往不足以满足需求。随着 MATLAB Web App 和实时数据流的普及,我们需要考虑图例在交互环境下的表现,以及处理百万级数据点时的性能瓶颈。
#### 示例 7:交互式图例(点击隐藏曲线)
这是一个令人兴奋的功能,但在旧版本的教程中常被忽略。我们可以让图例变成一个“开关”:点击图例中的某一项,对应的曲线就会从图表中消失。这对于探索性数据分析(EDA)极其有用。
% 生成密集数据
x = linspace(0, 10, 1000);
y1 = sin(x); y2 = cos(x); y3 = x/10;
% 绘图
p1 = plot(x, y1, ‘DisplayName‘, ‘Sine‘); hold on;
p2 = plot(x, y2, ‘DisplayName‘, ‘Cosine‘);
p3 = plot(x, y3, ‘DisplayName‘, ‘Linear‘);
hold off
% 创建图例
lgd = legend(‘show‘);
% 开启交互模式
% ItemHitFcn 属性定义了当用户点击图例项时的回调函数
% 这里我们使用一个内置的匿名函数来切换线条的可见性
lgd.ItemHitFcn = @(src, event) toggleLine(src, event);
% 定义回调函数
function toggleLine(src, event)
% 获取被点击的图例项对应的图表对象
hObj = event.Peer;
% 切换可见性状态
if strcmp(hObj.Visible, ‘on‘)
hObj.Visible = ‘off‘;
else
hObj.Visible = ‘on‘;
end
end
技术解读: 这段代码展示了 MATLAB 面向对象编程的魅力。我们不再仅仅是生成一张图片,而是构建了一个可交互的应用程序界面。ItemHitFcn 是连接用户操作与程序逻辑的桥梁。
#### 示例 8:大数据环境下的性能调优
当我们处理超过 10 万个数据点时,图例的渲染可能会变得卡顿。这在实时监控系统中是不可接受的。以下是我们生产环境中总结的优化策略。
% 模拟大数据
bigData = rand(100000, 5);
% 策略 1: 仅在绘图结束后更新图例一次
figure;
h = plot(bigData); % h 是一个包含 5 条线的向量
% 策略 2: 避免使用复杂的字符串格式化,使用索引或简短代码
labels = {‘Ch1‘, ‘Ch2‘, ‘Ch3‘, ‘Ch4‘, ‘Ch5‘};
% 使用句柄数组直接创建图例,这是最快的方法
% 它避免了 MATLAB 搜索 ‘DisplayName‘ 属性的开销
lgd = legend(h, labels);
% 策略 3: 关闭不必要的图例重绘
% 在循环更新数据时,最好先删除图例,更新完数据后再重绘
% 但在静态展示中,我们可以优化其渲染层次
lgd.Box = ‘off‘; % 去除边框可以减少 GPU 渲染负担
常见问题与解决方案(FAQ)
在探索 legend 函数的过程中,你可能会遇到以下一些棘手的问题。让我们看看如何解决它们。
Q1: 如何在图例中显示 LaTeX 数学公式?
MATLAB 的图例完美支持 LaTeX 解释器。你只需要在字符串中使用 TeX 语法即可。这对于学术图表来说是一个必备功能。
x = linspace(0, 10);
plot(x, exp(x))
% 使用 \it 表示斜体,^ 表示上标
% 注意:在 2026 年的 MATLAB 中,默认解释器可能更改为 ‘latex‘,但显式指定总是更安全
legend(‘Exponential Growth: $e^{x}$‘, ‘Interpreter‘, ‘latex‘)
Q2: 我只想显示特定几条线的图例,该怎么隐藏不需要的?
这是一个非常常见的需求。比如你绘制了 5 条辅助线,但只想在图例中显示主要的 2 条。你不需要重新绘图,只需获取图例句柄并操作它,或者在绘图时通过 ‘HandleVisibility‘ 属性直接隐藏特定线条的身份。
x = linspace(0, 10);
p1 = plot(x, sin(x), ‘DisplayName‘, ‘Visible Data‘); hold on;
p2 = plot(x, cos(x), ‘DisplayName‘, ‘Visible Data‘);
% 关键点:设置 HandleVisibility 为 ‘off‘,legend 函数将完全“看不见”这两条线
p3 = plot(x, 0.5*sin(x), ‘LineStyle‘, ‘--‘, ‘HandleVisibility‘, ‘off‘);
p4 = plot(x, 0.5*cos(x), ‘LineStyle‘, ‘--‘, ‘HandleVisibility‘, ‘off‘);
% 添加图例,只会显示 p1 和 p2
lgd = legend(‘show‘);
更灵活的方法是在创建图例时只传入你想要的特定句柄数组,这样不会影响原始对象的其他属性:
% 只为 p1 和 p2 创建图例
legend([p1, p2], {‘Sine‘, ‘Cosine‘})
Q3: 图例遮挡了数据怎么办?
除了调整 INLINECODE7a20fff1,我们还可以利用 INLINECODE7c783c35 属性或者将图例放置在坐标轴外部。
% 横向排列图例通常可以节省垂直空间,或者将其置于坐标轴外侧
% ‘southoutside‘ 会自动调整坐标轴大小以适应底部的图例
legend({‘Data 1‘, ‘Data 2‘, ‘Data 3‘}, ‘Orientation‘, ‘horizontal‘, ‘Location‘, ‘southoutside‘)
总结与展望
在 MATLAB 中为坐标轴添加图例是一项看似简单却暗藏玄机的技能。我们今天从基础的 legend(‘Sine‘, ‘Cosine‘) 语法出发,学习了如何使用元胞数组优化代码结构,如何显式地控制多坐标轴中的图例,以及如何通过调整位置和样式来满足严格的出版要求。
展望 2026 年,数据可视化正朝着更加智能化和交互化的方向发展。我们不仅仅是编写代码,更是在构建数据交互的界面。掌握 legend 函数的高级用法,结合 AI 辅助编程的思想,将极大地提升你图表的可读性和专业度。
下一次,当你打开 MATLAB 编辑器时,不妨尝试使用上述技巧,或者试着让 AI 帮你生成一段复杂的图例配置代码。你会发现,让数据说话,其实并不难。
下一步建议: 你可以尝试探索 annotation 函数,它允许你在图形的任意位置创建更加自由的文本框和箭头,配合图例使用,效果更佳。同时,了解 MATLAB Graghics Object 的层级结构(Figure-Axes-Legend)将是你进阶之路上必不可少的一环。