目录
[11.5创建具有两个 y 轴的图(yyaxis)](#11.5创建具有两个 y 轴的图(yyaxis))
11.6对数坐标图(semilogx、semilogy和loglog)
11.4对匿名函数绘制二维线图(fplot)
|-----------------|--------------------------------|---------------------------|---------------------------------|
| 功能 | 语法 | 返回对象 | 示例 |
| 绘制 f(x) | fplot(f, [xmin, xmax]) | FunctionLine | fplot(@(x)x.^2, [-1, 1]) |
| 绘制参数方程 | fplot(xt, yt, [tmin, tmax]) | ParameterizedFunctionLine | fplot(@cos, @sin, [0, 2*pi]) |
| 自定义样式 | fplot(..., 'Name', Value, ...) | 同上 | fplot(@sin, 'LineWidth', 2) |
11.4.1. 核心概念:fplot 与 plot 的区别
- plot:需要你先计算出一系列离散的数据点 (x, y),然后用线连接这些点。plot(x, y) 绘制的是你给定的数据。
- fplot:你只需提供一个函数句柄,fplot 会自动地在指定区间内进行智能采样,并绘制出一条平滑的函数曲线。fplot(f) 绘制的是函数本身。
fplot 的优势在于它能自适应地选择采样点,在函数变化剧烈的地方增加采样密度,在平缓的地方减少采样,从而用更少的点画出更精确的曲线。
11.4.2. 绘制单个匿名函数 f(x)
这是 fplot 最核心的用法,直接传入一个关于 x 的函数句柄。
语法:
Matlab
fplot(f)
fplot(f, [xmin, xmax])
h = fplot(...) % 返回图形对象句柄
参数说明:
- f:函数句柄,通常是一个匿名函数,如 @(x) sin(x) ./ x。
-
xmin, xmax\]:可选,指定 x 的绘图区间。默认为 \[-5, 5\]。
Matlab
% 定义一个匿名函数
myFunc = @(x) sin(x) .* exp(-x/5);
% 在默认区间 [-5, 5] 绘制
figure;
fplot(myFunc);
title('在默认区间绘制');
% 在指定区间 [0, 10] 绘制
figure;
fplot(myFunc, [0, 10]);
title('在指定区间 [0, 10] 绘制');
grid on;
11.4.3在使用 fplot 时,最常遇到的警告是:
Warning:
Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an array with the same size as the input.
原因分析:
fplot 为了提高效率,会尝试向量化你的函数,即一次性传入一个向量 x,并期望得到一个同样大小的向量 y。如果你的函数中使用了无法处理向量的运算符(如 ^ 而不是 .^),就会触发此警告。
示例与解决:
Matlab
% 错误的写法(会触发警告)
badFunc = @(x) x^2; % 使用了矩阵幂 ^
fplot(badFunc, [-2, 2]); % MATLAB会发出警告并尝试修复
% 正确的写法(向量化)
goodFunc = @(x) x.^2; % 使用了数组幂 .^
fplot(goodFunc, [-2, 2]); % 运行流畅,无警告
核心原则:
在为 fplot 创建匿名函数时,始终使用数组运算符(.*, ./, .^)。
11.4.4绘制参数方程 x(t) 和 y(t)
fplot 也可以轻松绘制由参数方程定义的曲线,如圆、螺旋线等。
语法:
Matlab
fplot(xt, yt)
fplot(xt, yt, [tmin, tmax])
h = fplot(...)
参数说明:
- xt:关于参数 t 的 x 坐标函数句柄。
- yt:关于参数 t 的 y 坐标函数句柄。
-
tmin, tmax\]:可选,指定参数 t 的范围。默认为 \[-5, 5\]。
Matlab
% 定义一个圆的参数方程
xt = @(t) cos(t);
yt = @(t) sin(t);
% 绘制一个完整的圆 (t 从 0 到 2*pi)
figure;
fplot(xt, yt, [0, 2*pi]);
title('单位圆');
axis equal; % 保证x,y轴比例相同,使圆不被拉伸成椭圆
grid on;
11.4.5 fplot 常用的名称-值参数
与 plot 类似,fplot 也支持通过名称-值参数对来定制线条样式、颜色等。
|-----------------|------------|------------------------------|
| 参数名 | 描述 | 示例值 |
| LineColor | 线条颜色 | 'r', 'blue', [0, 0.5, 0.8] |
| LineStyle | 线条样式 | '--', ':', '-.' |
| LineWidth | 线条宽度 | 1.5, 2 |
| Marker | 数据点标记 | 'o', '+', '*' |
| MarkerSize | 标记大小 | 8, 10 |
| MeshDensity | 网格密度(采样点数) | 50 (默认), 100, 200 |
使用举例:
Matlab
f = @(x) tanh(x);
fplot(f, [-3, 3], 'LineWidth', 2, 'Color', [0.2 0.6 0.8], 'LineStyle', '-.');
title('自定义样式的双曲正切函数');
grid on;
11.4.6 fplot 返回的图形对象
这是 fplot 与 plot 的一个关键区别。
- fplot 返回的不是简单的 Line 对象,而是更专门的函数对象。
- fplot(f(x)) 返回 FunctionLine 对象。
- fplot(x(t), y(t)) 返回 ParameterizedFunctionLine 对象。
这些对象是 Line 对象的子类,它们不仅包含了线条的所有视觉属性,还额外保存了用于绘制的函数句柄。
这意味着你可以在绘图后,直接修改其底层的函数定义,图形会自动更新!
示例:
Matlab
% 绘制 sin(x)
h_func = fplot(@sin, [-2*pi, 2*pi]);
title('原始函数: sin(x)');
pause(2);
% 修改句柄中的函数,无需重新绘制!
h_func.Function = @(x) cos(x);
title('修改后函数: cos(x)');
11.4.7. 知识扩展
与 fplot 类似的函数:ezplot(不推荐)
在旧版本的MATLAB中,ezplot (Easy Plot) 也用于绘制函数。fplot 是 ezplot 的现代化和功能增强版。
为什么不推荐 ezplot?
- 性能与精度:fplot 的自适应采样算法更先进,绘图更快、更精确。
- 返回对象:fplot 返回可操作的 FunctionLine 对象,而 ezplot 的返回值在不同版本中行为不一致,功能有限。
- 一致性:fplot 的语法和名称-值参数对与MATLAB其他现代绘图函数(如 plot)更加一致。
结论:
在所有新项目中,都应优先使用 fplot。
绘制多函数
可以在同一个 fplot 调用中绘制多个函数,或者使用 hold on。
方法一:使用 hold on
Matlab
figure;
fplot(@sin, [-2*pi, 2*pi]);
hold on;
fplot(@(x) cos(x), 'r--');
legend('sin(x)', 'cos(x)');
方法二:传入句柄数组
Matlab
figure;
fplot([@sin, @cos], [-2*pi, 2*pi]);
legend({'sin(x)', 'cos(x)'});
fimplicit 绘制隐函数
对于形如 f(x, y) = 0 的隐函数(如 x^2 + y^2 - 1 = 0),应使用 fimplicit 函数,它是 fplot 在隐函数领域的姊妹函数。
Matlab
fimplicit(@(x,y) x.^2 + y.^2 - 1);
axis equal;
title('单位圆 (隐函数)');
11.5创建具有两个 y 轴的图(yyaxis)
|----------------------------|----------------------|---------------------------------------------|
| 命令 | 功能 | 作用范围 |
| yyaxis left | 激活左侧 Y 轴 | 之后的所有绘图、ylabel、set(gca, 'YColor')等命令都只作用于左侧 |
| yyaxis right | 激活右侧 Y 轴 | 之后的所有绘图、ylabel、set(gca, 'YColor')等命令都只作用于右侧 |
| xlabel / title | 设置X轴标签/标题 | 全局 ,无论当前激活哪个Y轴,都会作用于整个坐标区 |
11.5.1. 核心概念:为什么需要双Y轴?
在单Y轴图表中,所有数据共享同一个Y轴刻度。当你想在同一张图上绘制两组数据,例如:
- 温度(范围:20-30°C)和降雨量(范围:0-200mm)
- 股票价格(范围:100-150元)和成交量(范围:100万-500万股)
如果强行使用同一个Y轴,其中一组数据的波动趋势会因为刻度问题而变得几乎不可见。
双Y轴图表通过为左右两侧Y轴设置独立的刻度和标签,完美地解决了这个问题,使得两组数据都能清晰地呈现。
11.5.2. yyaxis 的核心语法与工作模式
yyaxis 的核心思想是"激活"一个Y轴侧,之后所有的绘图和标签设置命令都只会作用于这一侧。
语法
Matlab
yyaxis left % 激活左侧Y轴
yyaxis right % 激活右侧Y轴
工作流程
- 使用 yyaxis left 激活左侧Y轴。
- 绘制与左侧Y轴关联的数据(使用 plot, bar, stairs 等)。
- 设置左侧Y轴的标签(ylabel)。
- 使用 yyaxis right 激活右侧Y轴。
- 绘制与右侧Y轴关联的数据。
- 设置右侧Y轴的标签。
- 最后,设置共用的X轴标签和标题。
11.5.3. 不同使用方法的举例
11.5.3.1 基础示例:绘制温度与降雨量
这是最典型的应用场景,展示了如何将两组不同单位的数据绘制在一起。
Matlab
% 1. 准备数据
months = 1:12;
temperature = [5, 7, 12, 18, 22, 28, 31, 30, 25, 19, 12, 6]; % 温度 (°C)
rainfall = [80, 70, 90, 120, 150, 180, 200, 190, 140, 100, 80, 75]; % 降雨量 (mm)
% 2. 创建图表并激活左侧Y轴
figure;
yyaxis left;
% 3. 绘制温度数据并设置左侧Y轴
plot(months, temperature, 'o-', 'Color', 'r', 'LineWidth', 2);
ylabel('温度 (°C)', 'Color', 'r'); % 标签颜色与线条对应
set(gca, 'YColor', 'r'); % Y轴刻度颜色也与线条对应
% 4. 激活右侧Y轴
yyaxis right;
% 5. 绘制降雨量数据并设置右侧Y轴
bar(months, rainfall, 'FaceColor', 'b', 'Alpha', 0.5);
ylabel('降雨量 (mm)', 'Color', 'b');
set(gca, 'YColor', 'b');
% 6. 设置共用元素
xlabel('月份');
title('年度温度与降雨量关系');
grid on;
xticks(months);
11.5.3.2 高级示例:在同一侧绘制多条线
你可以很方便地在同一侧Y轴上绘制多条数据,它们将共享该侧的刻度。
Matlab
% 准备数据
x = linspace(0, 10);
y1 = sin(x);
y2 = cos(x);
y3 = exp(x/5);
figure;
% 左侧Y轴:绘制三角函数
yyaxis left;
plot(x, y1, 'b-');
hold on;
plot(x, y2, 'r--');
ylabel('三角函数值');
legend('sin(x)', 'cos(x)', 'Location', 'northwest');
% 右侧Y轴:绘制指数函数
yyaxis right;
plot(x, y3, 'g:', 'LineWidth', 2);
ylabel('指数函数值');
% 设置共用元素
xlabel('X轴');
title('多函数对比');
grid on;
11.5.4. 知识扩展
11.5.4.1 yyaxis 与旧版 plotyy 的区别
在R2016a版本之前,MATLAB使用 plotyy 函数来创建双Y轴图。现在,强烈推荐使用 yyaxis,原因如下:
|----------|--------------------------------|---------------------------------------------|
| 特性 | yyaxis ( 推荐 ) | plotyy ( 旧版 , 不推荐 ) |
| 语法 | 命令式 ,逻辑清晰,易于扩展 | 函数式 ,参数复杂,难以添加多条线 |
| 句柄控制 | 返回单个坐标区句柄,通过 yyaxis 切换 | 返回两个坐标区句柄,操作繁琐 |
| 兼容性 | 与现代绘图函数(如 hold on, legend)完美兼容 | 常与 hold on 等产生意外行为 |
| 灵活性 | 可以轻松地在任意一侧添加任意数量的图形 | 添加额外图形非常困难 |
结论:除非你在维护必须使用旧版MATLAB的代码,否则应始终使用 yyaxis。
11.5.4.2 获取两侧Y轴的属性
虽然 yyaxis 简化了操作,但有时你仍需直接获取或设置某一侧Y轴的属性。你可以通过坐标区的 YAxis 属性来访问。
Matlab
% 继续上面的例子
ax = gca; % 获取当前坐标区句柄
% 获取左侧Y轴的刻度范围
left_lim = ax.YAxis(1).Limits;
% 获取右侧Y轴的标签
right_label = ax.YAxis(2).Label.String;
% 修改右侧Y轴的刻度格式为科学计数法
ax.YAxis(2).TickLabelFormat = '%.1e';
这里,YAxis 是一个包含两个 ruler 对象的数组,YAxis(1) 对应左侧,YAxis(2) 对应右侧。
11.5.4.3 图例的智能处理
如示例11.5.3.2所示,当你在不同侧绘制了多条线后,调用 legend 会自动将所有线条的图例整合在一起,非常方便。你只需要在所有绘图完成后,调用一次 legend 即可。
11.6对数坐标图(semilogx、semilogy和loglog)
|--------------|---------------|---------------|--------------|----------------|
| 函数 | X 轴刻度 | Y 轴刻度 | 典型应用场景 | 示例 |
| semilogx | 对数 | 线性 | 频率响应、频谱分析 | semilogx(f, H) |
| semilogy | 线性 | 对数 | 指数增长/衰减、误差分析 | semilogy(t, N) |
| loglog | 对数 | 对数 | 幂律关系、分形几何 | loglog(x, y) |
11.6.1. 核心概念:为什么使用对数坐标?
在标准的线性坐标图中,坐标轴的刻度是均匀的(例如,1, 2, 3, 4...)。
但当数据的跨度非常大时(例如,从0.01到1000000),线性坐标图会产生严重问题:
- 小数值被"压扁":数值较小的数据变化会变得无法分辨。
- 大数值占据大部分空间:图表的大部分区域被大数值占据,无法看清细节。
对数坐标图通过将坐标轴的刻度转换为对数尺度(例如,0.01, 0.1, 1, 10, 100...)来解决此问题。
这使得:
- 关注数量级变化:能清晰地展示数据在不同数量级上的相对变化。
- 识别指数关系:在对数坐标下,指数关系 y = a * b^x 会呈现为一条直线。
- 展示宽动态范围数据:如频率响应、地震震级、信号频谱等。
11.6.2. 三种对数坐标函数
MATLAB提供了三个专门的函数来创建不同类型的对数坐标图。
- semilogx:X轴为对数刻度,Y轴为线性刻度。
- semilogy:Y轴为对数刻度,X轴为线性刻度。
- loglog:X轴和Y轴均为对数刻度。
它们的语法与 plot 函数几乎完全相同。
语法:
Matlab
semilogx(X, Y)
semilogy(X, Y)
loglog(X, Y)
semilogx(Y) % 当X是1:length(Y)时
semilogx(X, Y, LineSpec)
semilogx(X, Y, Name, Value, ...)
h = semilogx(...) % 返回图形对象句柄
参数说明:
- X, Y:数据向量或矩阵,用法与 plot 完全一致。
- LineSpec:线条规格符(如 'r-o')。
- Name, Value:名称-值参数对(如 'LineWidth', 2)。
11.6.3. 不同使用方法的举例
11.6.3.1 semilogx:X轴对数坐标
常用于分析频率响应、滤波器特性等。
示例:绘制一个一阶低通滤波器的幅频响应曲线。
Matlab
% 准备数据:频率
f = logspace(0, 5, 200); % 从10^0到10^5生成200个对数间隔的点
fc = 1000; % 截止频率
% 计算幅频响应
H = 1 ./ sqrt(1 + (f / fc).^2);
% 使用 semilogx 绘图
figure;
semilogx(f, H);
title('一阶低通滤波器幅频响应');
xlabel('频率 (Hz) - 对数坐标');
ylabel('幅值 |H(f)| - 线性坐标');
grid on;
% 添加标记以突出截止频率
hold on;
semilogx([fc, fc], [0, 1/sqrt(2)], 'r--');
text(fc*1.5, 1/sqrt(2), '截止频率');
11.6.3.2 semilogy:Y轴对数坐标
常用于显示指数增长/衰减过程,如人口增长、放射性衰变、细菌繁殖等。
示例:模拟细菌指数增长。
Matlab
% 准备数据:时间
t = 0:10;
N0 = 100; % 初始细菌数量
r = 0.5; % 增长率
% 计算细菌数量
N = N0 * exp(r * t);
% 使用 semilogy 绘图
figure;
semilogy(t, N, 'o-', 'LineWidth', 2, 'MarkerFaceColor', 'b');
title('细菌指数增长');
xlabel('时间 (小时)');
ylabel('细菌数量 - 对数坐标');
grid on;
% 注意:指数函数在对数Y轴下呈现为一条直线
11.6.3.3 loglog:双对数坐标
常用于分析幂律关系,如分形、网络科学、物理学中的各种标度律。
示例:绘制幂律函数 y = 5 * x^(-2)。
Matlab
% 准备数据
x = logspace(-2, 2, 100);
y = 5 * x.^(-2);
% 使用 loglog 绘图
figure;
loglog(x, y, 'r-', 'LineWidth', 2);
title('幂律关系 y = 5 * x^{-2}');
xlabel('X - 对数坐标');
ylabel('Y - 对数坐标');
grid on;
% 注意:幂律函数在双对数坐标下呈现为一条直线
11.6.4. 知识扩展
11.6.4.1 使用 plot + set 方法
你也可以先用 plot 绘图,然后通过设置坐标轴的 XScale 和 YScale 属性来转换为对数坐标。这提供了更大的灵活性。
Matlab
% 先用线性坐标绘图
plot(x, y);
% 然后设置坐标轴属性
set(gca, 'XScale', 'log'); % X轴变为对数
set(gca, 'YScale', 'log'); % Y轴变为对数
% 或者 set(gca, 'YScale', 'linear'); 变回线性
这种方法的好处是,你可以在一个脚本中动态地切换坐标轴类型,而无需重写绘图函数。
11.6.4.2 负值与零值问题
对数函数在数学上对非正数(零和负数)是无定义的。因此,当你尝试绘制包含零或负值的数据时,MATLAB会:
忽略这些点:这些数据点不会在图上显示。
给出警告:命令行窗口会提示 "Negative data ignored" 或类似信息。
解决方案:
- 检查数据:确保你的数据在预期的对数范围内。
- 数据偏移:如果数据是相对于某个基准值的偏差(例如,误差),可以考虑加上一个小的常数 c 使得所有数据都为正:semilogy(x, y + c)。
- 使用 symlog (Symbolic Log) 刻度:在某些领域(如信号处理),需要一种能同时显示正负值的对数刻度。MATLAB原生没有直接的 symlog 函数,但可以在 File Exchange 上找到用户贡献的实现。
11.6.4.3 坐标轴刻度标签格式
在对数坐标中,刻度是10的幂次。你可以自定义这些标签的显示格式。
Matlab
loglog(x, y);
h_ax = gca;
% 将刻度标签从 10^2, 10^3... 改为 100, 1000...
h_ax.YAxis.TickLabelFormat = '%.0f';