1. 为什么我们需要多图例?
如果你用Matlab画过稍微复杂一点的图,肯定遇到过这种情况:图里线条太多,一个图例根本放不下,或者即使放下了,也挤成一团,根本看不清。更头疼的是,有时候你想把不同类别的曲线分组标注,比如一组是实验数据,一组是理论模型,一组是不同参数下的对比,你希望它们各自有自己的“小标签”,而不是混在一个大图例里。
Matlab自带的 legend 函数,默认一个坐标轴(axes)只能有一个图例。你可能会想,那我多调用几次 legend 不就行了?我试过,结果很“感人”——后一个 legend 会直接把前一个覆盖掉,最后图上只剩下最后一个图例。这显然不是我们想要的。
那怎么办呢?原始文章里给了一个非常巧妙的思路:“造”多个坐标轴,但只“显示”一个。听起来有点绕,其实原理很简单。我们平时画图,都是在当前这个坐标轴(gca)上操作。Matlab允许我们在同一张图(figure)里创建多个坐标轴对象(axes),它们可以完全重叠。我们可以在每个坐标轴上单独创建自己的图例,然后把除了主坐标轴之外的其他坐标轴“隐藏”起来(‘visible’, ‘off’)。这样,从视觉上看,我们只有一个坐标轴和它上面的曲线,但实际上却“悬浮”着好几个独立的图例框,它们互不干扰,可以放在图的任何角落。
这个方法我用了好多年,在处理论文插图、项目汇报图表时特别管用。它能让你图的专业度瞬间提升一个档次,信息层次分明,再也不用担心审稿人或老板说“图例太乱看不清”了。接下来,我就手把手带你把这个技巧吃透,从原理到实战,再到我踩过的坑,全都告诉你。
2. 核心原理:玩转axes对象的“隐身术”
要理解这个技巧,你得先对Matlab的图形对象层次有个基本概念。最顶层是图形窗口(figure),相当于一张画布。画布上可以放一个或多个坐标轴(axes),每个坐标轴就像一块透明的玻璃板,你在这块板上画曲线、加标签、加图例。默认情况下,我们操作的都是“当前坐标轴”。
2.1 创建与定位“影子”坐标轴
关键操作来了:axes(‘position’, get(gca, ‘position’))。这行代码是精髓。
gca获取当前坐标轴(就是你画曲线那个)的句柄。get(gca, ‘position’)获取这个坐标轴在figure窗口中的位置和大小,这是一个四元向量[left, bottom, width, height],数值是归一化的(0到1之间)。axes(‘position’, pos, …)创建一个新的坐标轴,并把它放在和当前坐标轴一模一样的位置上。
这就好比,你在原来的玻璃板(主坐标轴)上,又严丝合缝地盖上了另一块完全一样的玻璃板(新坐标轴)。两块板子重叠了。
% 假设我们已经画好了主图
plot(x, y1, ‘b-‘);
hold on;
plot(x, y2, ‘r–‘);
% 创建第一个“影子”坐标轴,位置和主坐标轴相同
axesNew1 = axes(‘position’, get(gca, ‘position’), ‘visible’, ‘off’);
注意,创建时我直接加上了 ‘visible’, ‘off’。这意味着,这块新玻璃板是“隐形”的。它上面的坐标轴线、刻度标签都不会显示。但是,它仍然是一个有效的坐标轴对象,我们可以在它上面执行 legend 命令。
2.2 在新坐标轴上“嫁接”图例
现在,axesNew1 是一个看不见的坐标轴。我们怎么把图例“放”上去呢?这里有个关键点:图例是属于某个特定坐标轴的。当你调用 legend(axes_handle, …) 时,你就是在指定这个图例“挂靠”在哪个坐标轴上。
但是,axesNew1 是空的,上面没有曲线啊?没错,所以我们不能直接 legend(axesNew1, {‘曲线1’, ‘曲线2’}),这样图例里没有对应的图形对象,会报错或者显示空白。
正确的做法是“传递”曲线句柄。我们在主坐标轴上画图时,最好把每条曲线的句柄保存下来。
% 画图时保存句柄
h1 = plot(x, y1, ‘b-‘, ‘DisplayNam


298

被折叠的 条评论
为什么被折叠?



