
MATLAB plot函数绘制多条曲线的几种方法
用 MATLAB 绘制多条曲线,常见需求包括:在同一坐标轴比较几组实验数据、把矩阵的每列作为一条曲线,或逐条添加数据并设置不同样式。plot 可以一次接收多组数据,也可以与 hold on 配合,分多次绘图。选哪种方式,主要取决于数据的组织形式和绘图过程是否需要逐步控制。
本文使用数值型横纵坐标举例,代码均可单独运行。MATLAB 版本不同,图形默认配色、名称值参数的写法以及部分图形功能可能略有差异;示例采用常见的 plot 语法,名称值参数尽量使用兼容性较好的逗号分隔写法。
一、绘制多条曲线前,先弄清数据的维度
最简单的用法是给 plot 一个向量作为纵坐标。MATLAB 会使用元素的序号作为横坐标:
x = 0:0.1:2*pi;
y = sin(x);
figure
plot(y)
这里横坐标相当于 1:numel(y),不是变量 x。如果横坐标代表实际的时间、距离或其他物理量,应明确传入 x:
x = 0:0.1:2*pi;
y = sin(x);
figure
plot(x, y)
xlabel('x')
ylabel('sin(x)')
对一维曲线,x 和 y 应当是长度相同的向量。行向量和列向量通常都可以,但不应依赖不清晰的维度安排;调试时可用 size 或 numel 检查数据长度。
二、方法一:把多条曲线放在矩阵的列中
当多组曲线共享同一组横坐标,而且样本点数一致时,把纵坐标整理成矩阵通常最简洁。以下示例中,Y 的每一列是一条曲线:
x = linspace(0, 2*pi, 200).';
Y = [sin(x), ...
cos(x), ...
0.5*sin(2*x)];
figure
plot(x, Y)
xlabel('x')
ylabel('y')
legend('sin(x)', 'cos(x)', '0.5 sin(2x)', ...
'Location', 'best')
grid on
Y 的尺寸为“样本点数 × 曲线数”。当横坐标是向量而纵坐标是矩阵时,向量长度需要与矩阵的一条维度相匹配;MATLAB 据此沿矩阵的行或列绘制多条线。若数据是方阵,两个维度长度相同,单看尺寸无法表达你希望哪一维代表样本点。为了避免方向误判,最好把数据整理成“每列一条曲线”,并确保横坐标长度对应行数;必要时使用转置运算符 .'(非共轭转置)调整方向。
例如,已有数据每一行是一条曲线,可以转置后再画:
x = 1:5;
Yrow = [1 2 3 4 5; ...
2 3 4 5 6; ...
3 4 5 6 7];
figure
plot(x, Yrow.')
xlabel('样本序号')
ylabel('数值')
legend('曲线1', '曲线2', '曲线3', 'Location', 'best')
这里 Yrow.' 将原来的“每行一条”转成“每列一条”。对于实数矩阵,' 与 .' 结果相同;对于复数数据,' 还会取复共轭,因此只想交换行列时,使用 .' 更能表达意图。
若横坐标也有多组,并且每条曲线的采样点一一对应,可以将 X 与 Y 整理为尺寸相同的矩阵,按对应列绘图:
X = [1 1 1; ...
2 2 2; ...
3 3 3; ...
4 4 4];
Y = [1 2 3; ...
2 4 3; ...
3 3 5; ...
4 5 4];
figure
plot(X, Y)
legend('曲线1', '曲线2', '曲线3', 'Location', 'best')
grid on
当矩阵的行列含义不明显时,不要只靠 MATLAB 自动判断。显式转置或分别传入向量,可以减少尺寸相同却方向相反造成的错误。
三、方法二:在一次 plot 调用中传入多组 x、y
如果每条曲线的横坐标不同,或者每组数据长度不同,可以在一次调用中按 x,y 成对传入多组数据:
x1 = 0:0.1:2*pi;
y1 = sin(x1);
x2 = 0:0.2:2*pi;
y2 = cos(x2);
x3 = [0 1 2 3 4];
y3 = [0 1 0 -1 0];
figure
plot(x1, y1, x2, y2, x3, y3)
xlabel('x')
ylabel('y')
legend('sin(x)', 'cos(x)', '离散数据', 'Location', 'best')
grid on
参数顺序必须保持成对:x1, y1, x2, y2, ...。每一对内部的横纵坐标长度应匹配。不同曲线之间则可以有不同长度,也可以使用不同横坐标。若某条曲线漏传了一个参数,或顺序写成 x1, x2, y1, y2,MATLAB 可能报错,也可能把数据解释成非预期的参数组合。
一次调用适合数据都已准备好的情况,调用次数少,代码集中。若曲线是循环生成、数量不确定,或需要在循环中逐条更新,使用 hold on 通常更方便。
四、方法三:使用 hold on 逐条叠加
hold on 会让当前坐标轴保留已有图形,后续绘图继续叠加;hold off 恢复默认行为。下面用循环逐条绘制多条曲线:
x = linspace(0, 2*pi, 200);
figure
hold on
for k = 1:4
y = sin(k*x) / k;
plot(x, y, 'LineWidth', 1.2)
end
hold off
xlabel('x')
ylabel('y')
legend('k=1', 'k=2', 'k=3', 'k=4', 'Location', 'best')
grid on
hold on 和 hold off 作用于当前坐标轴,不是对所有图窗永久生效的全局开关。因此,创建或切换坐标轴后,最好在目标坐标轴上明确设置保持状态。绘图状态还受坐标轴属性影响;不确定状态时,可在需要保留曲线的代码段前显式写 hold on,绘制结束后写 hold off,避免依赖之前交互操作留下的状态。
如果有多个坐标轴,推荐把目标坐标轴句柄传给绘图函数,而不是依赖当前轴。这样可以避免图形被画进错误的子图:
x = 0:0.1:2*pi;
figure
ax = axes;
hold(ax, 'on')
for k = 1:3
y = sin(k*x);
plot(ax, x, y, 'LineWidth', 1.2)
end
hold(ax, 'off')
xlabel(ax, 'x')
ylabel(ax, 'y')
legend(ax, 'sin(x)', 'sin(2x)', 'sin(3x)', ...
'Location', 'best')
grid(ax, 'on')
较老版本 MATLAB 对部分函数的坐标轴句柄用法可能不同;若当前版本不接受上述调用形式,可先将坐标轴设为当前轴,再调用相应函数。不要因此省略坐标轴管理,尤其是在多子图或函数封装中。
五、方法四:为每条曲线设置线型、颜色和标记
plot 支持线型、标记符和颜色的简写组合,例如 '--o' 表示虚线并带圆圈标记。也可以使用名称值参数设置属性:
x = linspace(0, 2*pi, 25);
figure
plot(x, sin(x), '-o', ...
'LineWidth', 1.5, ...
'MarkerSize', 5)
hold on
plot(x, cos(x), '--s', ...
'LineWidth', 1.5, ...
'MarkerSize', 5)
hold off
legend('sin(x)', 'cos(x)', 'Location', 'best')
xlabel('x')
ylabel('y')
grid on
颜色、线型和标记可以帮助读者区分数据,但不要只靠颜色传递关键信息;打印成灰度或面向色觉差异人群时,线型和标记也很重要。显式指定颜色时,可使用颜色名称或 RGB 三元组。RGB 各分量通常取 0 到 1 之间的数值:
x = linspace(0, 2*pi, 200);
figure
plot(x, sin(x), 'Color', [0.00 0.45 0.74], ...
'LineWidth', 1.8)
hold on
plot(x, cos(x), 'Color', [0.85 0.33 0.10], ...
'LineStyle', '--', 'LineWidth', 1.8)
hold off
legend('sin(x)', 'cos(x)', 'Location', 'best')
grid on
颜色分量超出有效范围、RGB 向量长度不对,或把线型字符串误写成不存在的选项,都会导致报错。不要把线宽、标记尺寸等数值参数当成任意字符串传入。每个属性可接受的取值及版本支持情况,应以当前 MATLAB 的 plot 和图形属性文档为准。
六、用图形句柄精确控制每条线
当曲线较多、图例需要按指定顺序显示,或后续还要修改某一条线时,保存 plot 返回的图形句柄会更稳妥:
x = linspace(0, 2*pi, 200);
figure
h1 = plot(x, sin(x), 'LineWidth', 1.5);
hold on
h2 = plot(x, cos(x), '--', 'LineWidth', 1.5);
h3 = plot(x, sin(x).*cos(x), ':', 'LineWidth', 1.8);
hold off
legend([h1 h2 h3], ...
{'sin(x)', 'cos(x)', 'sin(x)cos(x)'}, ...
'Location', 'best')
句柄也可以用于之后修改属性:
set(h1, 'Color', [0 0.45 0.74])
set(h2, 'LineWidth', 2)
明确指定句柄后,图例不会因为坐标轴中后来添加的其他图形对象而轻易错配。使用图例名称值参数时,注意区分图例自身的设置和曲线对象属性;不同版本对字符串数组、字符向量元胞数组等输入形式的支持有差异。示例中的字符向量元胞数组写法在较多版本中都适用。
七、常见错误与排查方法
1. 横纵坐标长度不一致
单条曲线的 x 和 y 长度必须对应。可先检查:
size(x)
size(y)
numel(x)
numel(y)
若一个是矩阵、另一个是向量,检查向量长度是否与矩阵的一维相符,并确认希望按行还是按列生成曲线。不要为了让代码“能运行”就随意转置数据,先确认每个维度代表什么。
2. 忘记区分“样本点”和“曲线”所在维度
实验数据常见两种组织方式:行表示样本、列表示变量,或行表示曲线、列表示时间点。两种方式都合理,但调用 plot 时需要与其一致。建议在变量名或注释中说明尺寸,例如“行是时间点,列是传感器”,并用 size(Y) 核对。
3. 重复调用 plot,前面的线被替换
在同一坐标轴上直接连续调用 plot,后一次绘图通常会替换前一次图形。需要叠加时,使用 hold on;如果不确定当前保持状态,显式设置它,不要依赖命令窗口里此前的操作。
4. 图例顺序和曲线顺序不一致
legend 的名称通常按图形对象顺序对应。若中间还有参考线、拟合线或其他对象,直接按文字数量填写可能造成错配。可保存曲线句柄,并通过 legend([h1 h2], ...) 明确指定要纳入图例的对象。
5. 误把矩阵绘图当成逐行绘图
当向量长度与矩阵的行数、列数都匹配时,尺寸本身不足以体现数据含义。特别是方阵,应主动转置或拆成明确的向量对进行绘制。绘图方向不符合预期时,先检查矩阵尺寸和转置,而不是先调整坐标轴范围。
6. 数据中存在 NaN、Inf 或空值
数值数组中的非有限值可能造成线段中断或数据点不显示;例如,NaN 常用于在一条线中制造断点。绘图前可检查 isfinite,确认缺失值是有意保留还是数据处理产生的。不要未经判断就用插值或删除操作填补缺失值,这会改变数据表达。
7. 多条线颜色相近,或者图例遮住数据
曲线数量增加后,默认颜色循环可能难以区分。可以同时调整颜色、线型和标记,并将图例放在合适的位置。'Location','best' 会尝试选择较合适的位置,但不保证所有数据布局下都完全避开曲线;必要时可选择固定位置或将图例移到坐标轴外。
八、参数范围、版本差异与数据安全
plot 的参数组合并不是任意的。常用的数值向量和矩阵要满足相应的尺寸关系;不同长度的曲线适合用多组成对的 x,y 形式。样式简写必须符合 MATLAB 支持的线型、标记和颜色语法,名称值参数的属性名与属性值也必须匹配。绘图接受哪些数据类型、名称值参数如何写,以及某些属性的具体限制,可能因 MATLAB 版本和图形对象类型而异;遇到版本兼容问题,应查阅本机对应版本的 plot 帮助,而不要假定所有版本行为完全一致。
从安全角度看,plot 的用途是创建或更新图形对象,不是执行代码的接口,也不是安全隔离机制。正常绘制数值数组不会因为数组内容像 MATLAB 命令就自动执行这些命令;但这不代表可以把不可信输入随意用于整个程序。避免把外部输入拼接进 eval 等动态执行代码中,也不要把未经核验的数据当作可信的变量名、属性名或文件路径。若绘图封装需要接受外部数据,应检查数据类型、尺寸、有限值及预期范围,并明确处理异常输入。对未知来源的文件,应按照组织的安全规范审查和导入;单独使用 plot 并不能使不可信文件变安全。
九、如何选择绘图方式
- 共享横坐标、样本数一致,纵坐标能整理成矩阵:优先使用
plot(x, Y),通常每列对应一条曲线。 - 每条曲线的横坐标或长度不同:使用
plot(x1, y1, x2, y2, ...)。 - 曲线在循环中逐条生成,或需要分步控制:使用
hold on,并在需要时保存图形句柄。 - 矩阵行列含义不清楚,尤其是方阵:先整理数据方向,或明确传入每条曲线的向量对。
多曲线绘图的核心不是记住更多参数,而是先确认数据维度,再选择与数据结构匹配的调用形式。把“每条线对应哪些横纵坐标”表达清楚,配合明确的坐标轴状态、图例和样式设置,就能避免大多数绘图错误。




