本人日常用电脑为Mac,window操作也一样的嘞
然后我用的是2020版的,以下所有命令针对2020版
最后本教程对于至少有一点点基础(无论是啥语言基础)的兄弟姐妹们使用,有基础食用更香哦~(因为我没讲语法,语法同其他语言)
0. 注意事项
0.1. 操作界面
这是我们软件的基础配置界面,清楚明了。但是有一个重点:
- 我们可以看到图中的工作目录,这个工作目录是我们输入代码的默认地址,但在其他地址下无法对这里面的文件进行操作(如我们在Matlab文件夹下就无法对Document文件夹下的文件进行操作)。
0.2. 代码操作方式
Matlab和其他的语言稍有不同:
Matlab被称为脚本语言,他具有类似于shell编程(不知道也没事)的性质,就是我们的所有操作实质上都是在命令行中完成的。
即使是运行文件,也相当于把文件中的代码一条一条放到命令行中运行。所以我们运行文件的时候就是输入文件的名字,就能运行文件了。
所以说简单也很简单,Matlab语言主要就是:
- 直接使用命令行编程操作;
- 新建脚本,在脚本中编写自己要运行的程序;
- 在命令行中打文件名运行。
0.3. 分号(😉
分号有什么用?给一个非常简单的例子:
学过语言的同志的可能已经明白了,就是没加分号,命令行就自动的会把该行返回值打印出来。不懂的也没事,就是把这一行得到的结果打印出来而已。
(这个非常适用在debug的时候,可以把你代码的过程打印出来)
1. 基础命令
原本我还想分命令行命令和在jio本中常用的命令的,想了一下,不都是一样的么,毕竟前面也说了jio本语言文件内和命令行是一样der
1.1. clear命令
用于清除工作区中的变量,来个清楚易懂的例子:
所以就是一个删除变量用的命令咯,如果不输入变量名就会清空所有变量!!注意!!
1.2. clc命令
clc就是清空屏幕~注意别打成clear就行了,要不然心累der
略了略了
1.3. who和whos命令
who和whos可以用来查看我们当前有哪些变量,但ta们有什么差别呢?
who单纯是用来看变量名儿,whos还能看到很多细节:
哎,为啥size是1*1啊?学了别的语言的可能会有人对这个size有疑惑,其实Matlab中数据自动是以矩阵存储的,所以一个数字就是一个一行一列的矩阵。
1.4. %
- 这是注释
- 这是注释
- 这是注释
1.5. 输出命令
Matlab中常用的输出命令为disp,类似于Python中的print。
效果很简单,就是把输入的参数输出来然后自动换行。
disp("我是输出命令")
这里有个注意的事项,就是千万别把sprintf当成一个输出命令了。
学过C的同学都应该很习惯用printf命令,是一个格式化输出命令。但是Matlab中的sprintf是一个格式化字符串的命令,而不是格式化输出到屏幕。是什么意思呢?意思就是sprintf单纯是格式化字符串然后返回字符串,并不会打印到屏幕上,我们可以看一个例子:
1.6. 文件操作命令
我们平常会运行脚本文件,也要编辑脚本文件:
% 前提是在当前文件目录下有该文件
>> Main % 运行Main.m文件
>> edit Main % 打开Main.m文件进行编辑
>> help Main % 打印该文件的最前面的注释,用于辅助使用者了解该文件
2. 应用命令
2.1. 一元方程
2.1.1. 计算
一元(无论是有参还是无参)方程,一般都使用solve函数进行计算。
solve函数的第一项为方程,第二项表示要计算的未知量
如下举例:
%% 解一元方程
clear; % 清除工作区变量,防止变量影响
syms x; % 一元函数未知数必须定义
r = solve(x^2 - 2 * x - 1, x);
disp(r);
或者我们再来一个有参数的:
%% 解一元方程
clear; % 清除工作区变量,防止变量影响
syms a b x; % 一元函数未知数必须定义
r = solve(a * x^2 - 5 * b * x - 1, x);
disp(r);
以上,我们得到了分数公式,但是有时为了便于计算,我们也需要一些精确的值,此时我们就可以用%f将其格式化输出:
%% 解一元方程
clear; % 清除工作区变量,防止变量影响
syms a b x; % 一元函数未知数必须定义
r = solve(x^2 - 5 * x - 1, x);
disp(sprintf("r: %f, %f!", r));
但是用%f只能精确到后六位,所以我们也可以使用vpa函数得到小数点后n位的小数值:
%% 解一元方程
clear; % 清除工作区变量,防止变量影响
syms a b x; % 一元函数未知数必须定义
r = solve(x^2 - 5 * x - 1, x);
r = vpa(r, 18);
disp(r);
解 一元方程 成功~
2.1.2 一元方程绘制
在Matlab中我们经常会想要绘制一些图像,然后我们就需要用到一些函数去帮助我们绘制一些函数图像了。
在这里我们用inline函数载入我们的函数,封装为一个函数对象(inline只是用于前期学习)。
然后使用ezplot显示我们的图形,同时可以确定显示的范围。
那我们来举个栗子:
clear; % 清空工作区
f = inline("x^2 + 2*x + 1"); % 载入一元函数
ezplot(f, -4, 4); % 调节范围,显示函数
hold on; % 保留图像
wow,图像就绘制出来了呢!但是有没有人注意到我在最后还写了一个hold on?我注释上写的是保留图像,其实ta是在多线绘制的时候会用到的嘞。
有时我们需要在同一张图上绘制多个函数,此时我们就不能删除过去绘制的图像,hold on在此处起保留过去绘制的图像的作用。
在这里我们再加入两条曲线,用于体现hold on的作用。新加入的曲线名字再图像的上方。
这已经是最简单的图像绘制了,同时我们可以玩点花的:使用plot函数可以进行单点绘制和多点绘制(也就是在一个点上画画,或者将多点连线绘制)
plot(1:10, [3 2 5 7 5 8 9 2 4 5], "--*");
属实是花了点对吧,详细的等我需要了我再去查~
2.2. 线性方程组求解(矩阵的计算)
温馨提示:本节主要使用矩阵的计算,建议先好好了解一下矩阵
我们经常求解一些线性方程组,然后求多个变量的值。之前学到的求解一元方程的方法已经无法适用了,因为一个方程里面现在有了多个变量,而且有多个方程。那我们不如换种思路,用线性代数中学到的矩阵进行计算。
我们来举个例子: { 4 x 1 + x 2 − 2 x 3 = 1 2 x 1 + 2 x 2 + x 3 = 2 3 x 1 + x 2 − x 3 = 3 \begin{cases} 4x_1 + x_2 - 2x_3 = 1 \\ 2x_1 + 2x_2 + x_3 = 2 \\ 3x_1 + x_2 - x_3 = 3 \end{cases} ⎩⎪⎨⎪⎧4x1+x2−2x3=12x1+2x2+x3=23x1+x2−x3=3
在这个公式中,我们已经把x1, x2, x3 的顺序排好了,我们只需要直接列出这个线性方程组的增广矩阵: [ 4 1 − 2 1 2 2 1 2 3 1 − 1 3 ] \left[ \begin{matrix} 4 & 1 & -2 & 1 \\ 2 & 2 & 1 & 2 \\ 3 & 1 & -1 & 3 \end{matrix} \right] ⎣⎡423121−21−1123⎦⎤,就能根据我们的知识推到出公式 A x = B Ax=B Ax=B(其中A为系数矩阵,B为结果矩阵)。
所以我们可以得到公式: [ 4 1 − 2 2 2 1 3 1 − 1 ] [ x 1 x 2 x 3 ] = [ 1 2 3 ] \left[ \begin{matrix} 4 & 1 & -2 \\ 2 & 2 & 1 \\ 3 & 1 & -1 \end{matrix} \right] \left[ \begin{matrix} x_1 \\ x_2 \\ x_3 \end{matrix} \right] =\left[ \begin{matrix} 1 \\ 2 \\ 3 \end{matrix} \right] ⎣⎡423121−21−1⎦⎤⎣⎡x1x2x3⎦⎤=⎣⎡123⎦⎤
所以怎么进行计算得到 x 1 , x 2 , x 3 x_1, x_2, x_3 x1,x2,x3的值就是一个问题了,我们知道要计算 A x = B Ax=B Ax=B中x的值,对这个公式进行转换就可以得到 x = A − 1 B x=A^{-1}B x=A−1B(为啥是 A − 1 B A^{-1}B A−1B而不是 B / A B/A B/A就不用我解释了吧)
那么 x = A − 1 B x=A^{-1}B x=A−1B在代码中怎么使用呢?
首先我们用代码构建两个矩阵用于计算:
%% 构建方程
clear;
A = [
4 1 -2;
2 2 1;
3 1 -1
]; % 构建矩阵A
B = [
1;
2;
3
]; % 构建矩阵B
然后我们计算x:
>> x = A \ B;
% 唉,这里用的是'\',而不是'/',为啥呢?
根据上面我们所说的,矩阵计算的左右未知是不能变换的。所以我们自然不能写成 B / A B/A B/A,但’\‘是什么意思呢?其实我们用’\‘是用于表示左边的数是逆矩阵(或倒数),在本体中也就是表示’\'的左边是 A − 1 A^{-1} A−1。
所以这里可以解释为 x = A − 1 B x=A^{-1}B x=A−1B。
那与此同理,我们重新构建一个方程 [ x 1 x 2 x 3 ] [ 4 1 − 2 2 2 1 3 1 − 1 ] = [ 1 2 3 ] \left[ \begin{matrix} x_1 \\ x_2 \\ x_3 \end{matrix} \right] \left[ \begin{matrix} 4 & 1 & -2 \\ 2 & 2 & 1 \\ 3 & 1 & -1 \end{matrix} \right] =\left[ \begin{matrix} 1 & 2 & 3 \end{matrix} \right] ⎣⎡x1x2x3⎦⎤⎣⎡423121−21−1⎦⎤=[123],也就是 x A = C xA=C xA=C,根据上面我们也就有经验了,这里应该结果就是: x = C A − 1 x=CA^{-1} x=CA−1。
所以这里我们的结果也就和我们普通的认知一样了,因为’/‘就是表示’/'右边的值为逆矩阵(或倒数),在本题中就是指右边为 A − 1 A^{-1} A−1:
>> x = C / A;
这样就能通过矩阵计算,用于计算线性方程组了。
2.3. 积分的计算
2.3.1. 不定积分
积分有特有的函数用于计算,非常的简单(积分的概念就不讲咯)
不定积分与定积分是用同一个函数进行计算:int函数。
因为非常简单,我们就直接上栗子咯:
%%计算不定积分
clear;
syms x; % 定义一个符号x
f = x^2 + 1; % 定义一个函数
F = int(f, x); % 计算不定积分
disp(F); % 显示原函数
2.3.2. 定积分
是不是很简单,那我们再来看一下定积分:
%%计算定积分
clear;
syms x; % 定义一个符号x
f = x^2 + 1; % 定义一个函数
res = int(f, x, -5, 5); % 计算定积分
disp(res); % 显示原函数
当我们要计算定积分和不定积分的时候用int函数就可以,差别也就只是在最后两个用于确定范围的两个参数上,很简单der
2.3.3. 积分的图绘制
我们经常用到的积分图的绘制是啥?毋庸置疑,我们常学到的就是积分之间相交的位置进行填色。
上代码:
%% 绘制积分图像
clear;
x = 0: 0.01: pi; % 设置x是步长为0.01的0~pi的区间数组
y1 = sin(x);
y2 = exp(x);
figure; % 新建一个figure图像框体
hold on; % 保留绘制,保证多个绘制图像一起出现
subplot(221); % 新建子窗体,221:2行2列,第一个
fill(x, y1, 'r'); % 根据区间数组x,函数y1,画图并填充红色
title('y = sinx'); % 设置标题
subplot(222);
fill(x, y2, 'b');
title('y = e^x');
subplot(223);
fill([x, fliplr(x)], [y1, fliplr(y2)], 'g'); % 填充区间数组x中,y1和y2之间的位置
title('y = e^x & y = sinx');
hold off; % 解除保留
代码其实很好理解,就是我们建立好了方程之后进行了一个代入和填色。但是有两个地方需要解释一下:
-
单个函数颜色的填充是怎么填充的?这个填充其实是第一个点和最后一个点连线,然后和曲线形成的一个封闭区间,然后将封闭区间进行填色,我们可以改变一下区间值进行理解:
-
第二是这个fill函数是咋用的?首先我们要知道fliplr函数是干啥用的:
- fliper的函数是将向量反向,本体是将区间倒置
然后两个参数,第一个参数是将作用域正反向都给了一遍,然后第二个参数将两个函数正反向也给了一遍。什么意思呢?其实很简单,就是把这个图像画了一圈呗,这样才能把这个颜色区域围起来。看图吧:
我们图都画出来了,定积分当然也好求呀:
%% 求定积分
syms x;
f = 'exp(x) - sin(x)';
res_int = int(f, x, 0, pi);
disp(res_int);
2.3.4. 二重积分
二重积分的概念可能要先复习一下,一重积分计算的是面积,二重积分计算的就是体积咯。然后一重积分是通过多个梯形累加得到的面积,二重积分就是通过多个梯柱累加得到的体积。还有一种方法,就是一重积分是一根线平移扫过的那个面积,其实二重积分就是一个面平移扫过的体积。
和一重积分一样,我们可以通过进行积分得到原函数,也可以求到不定积分,公式为 ∬ f ( x , y ) d x d y \iint{f\left(x, y\right)}dxdy ∬f(x,y)dxdy。同时要求定积分的话需要给定一个面中的范围:比如 x = 0 , x = 1 , y = 0 , y = 1 x=0,x=1,y=0,y=1 x=0,x=1,y=0,y=1围起来的图形,知道图形后就可以知道: x m i n , x m a x , y m i n , y m a x x_{min},x_{max},y_{min},y_{max} xmin,xmax,ymin,ymax这四个值。
例如:
我们可以对这个面进行分析,估计
x
m
i
n
=
1
,
x
m
a
x
=
3
,
y
m
i
n
=
0
,
y
m
a
x
=
3
2
x
+
1
2
x_{min}=1,x_{max}=3,y_{min}=0,y_{max}=\frac{3}{2}x+\frac{1}{2}
xmin=1,xmax=3,ymin=0,ymax=23x+21,然后我们就可以使用这些代入得
∫
1
3
d
x
∫
0
3
2
x
+
1
2
f
(
x
,
y
)
d
y
\int_{1}^{3}dx\int_{0}^{\frac{3}{2}x+\frac{1}{2}}{f\left(x,y\right)}dy
∫13dx∫023x+21f(x,y)dy。就可以计算咯~
那我们再来个例子,上代码咯。
- 假设 f ( x , y ) = x 2 sin y f\left(x,y\right)=x^{2}\sin{y} f(x,y)=x2siny;
- 条件:由 x = 0 , x = 1 , y = 0 , y = x x=0,x=1,y=0,y=x x=0,x=1,y=0,y=x封闭形成的区间。
%% 计算二重积分
f = @(x,y)x.^2.*sin(y); % 定义匿名函数f,参数为x,y
ymax = @(x) x; % 定义匿名函数ymax,表示y的上界
res = integral2(f, 0, 1, 0, ymax); % 计算二重积分,integral2(fun, xmin, xmax, ymin, ymax)
disp(res);
在这里要注意一个点,我们在此用匿名函数来表示函数,表示时将所有运算符前加’.’,为了对应元素的计算,不按矩阵的规则。然后这个匿名函数不难,其实就是用函数名和参数表示了这个方程。
既然我们以这个函数举例子了,那我们也把这个函数画出来一下吧:
%% 画曲面
[x,y] = meshgrid(0:0.001:1, 0:0.001:1); % 设置x和y的区间数组
z = (x.^2.*sin(y)); % 使用一个z来代表这个函数
mesh(x,y,z); % 画出二维曲面图像
title('f(x,y) = x^2 * sin(y)');
2.4. 多项式计算
2.4.1. 建立多项式
我们经常能见到多项式,但我们怎么在计算机中表示出来呢?
其实表示多项式很简单。总所周知,多项式的每一项前面都是有系数的(即使没有这一项,不过就是系数为0而已)。
所以我们可以将多项式总结成一个系数数组!例如: y = 2 x 4 + 3 x 2 + 6 x + 9 y = 2x^4 + 3x^2 + 6x + 9 y=2x4+3x2+6x+9可以表示为 [ 2 , 0 , 3 , 6 , 9 ] \left[2, 0, 3, 6, 9\right] [2,0,3,6,9](这里要注意加上没有的项的系数,和顺序一定是按照指数倒序排列的)。
在明确了我们的函数表达方式之后我们就要在代码中建立我们的多项式方程了,话不多说,我们先上一串代码:
%% 建立多项式方程
p = [2 0 3 6 9]; % 录入多项式系数
y = poly2sym(p); % 构建多项式
fprintf("y = %s\n", y); % 打印多项式方程到屏幕
对照我们输入的系数不难发现就是我们需要的函数。
但不只是这样,这只是根据已有的系数直接代入得到方程而已。Matlab中还可以通过方程的根求出原函数,其实也就是通过韦达定理求解:
%% 使用根建立多项式
r = [2 5]; % 给定函数的根
p = poly(r); % 求根所属函数的系数
y = poly2sym(p); % 构建多项式
fprintf("y = %s\n", y); % 打印多项式方程到屏幕
其实就是加了一步,通过poly函数求出根的原函数系数,so easy~
2.4.2. 求导
其实求导的操作很简单也很统一:
求导就是在已知函数方程的情况下,通过polyder函数对我们需要求导的方程进行求导。
2.4.2.1. 多项式求导
话不多说先上代码了:
%% 多项式求导
p = [2 8 5 9 4];
y = poly2sym(p);
fprintf("y = %s\n", y); % 打印原函数
p_1 = polyder(p); % 求导得到新的系数
y_1 = poly2sym(p_1);
fprintf("y' = %s\n", y_1); % 打印导函数
不难发现我们在其中多加了一个步骤,也就是利用polyder函数将p变成了p_1。同时这里也要注意我们是将p变成了p_1,而不是将y变成了y_1。
从这里我们就能看出来了,其实我们的函数进行求导计算的时候,是直接对系数进行操作的,毕竟系数已经可以完全表示出我们的多项式方程了咯。
2.4.2.2. 乘积求导
其实乘积求导你看到代码的时候就会觉得和多项式求导一模一样,因为也就是函数换了种用法罢了,所以直接看代码吧:
%% 乘积求导
p1 = [2 5 2 3];
p2 = [8 1 3 5];
y1 = poly2sym(p1);
y2 = poly2sym(p2);
fprintf("原函数:\ny1 = %s \ny2 = %s\n", y1, y2); % 打印两个原函数
pres = polyder(p1, p2); % 进行乘积求导
yres = poly2sym(pres);
fprintf("导函数:\ny\' = %s\n", yres); % 打印导函数
是吧,其实就是在polyder函数中加了一个参数就会变成乘法求导了。
2.4.2.3. 商求导
然后商求导也就和乘法求导一样,甚至还是用同一个函数,不过哪里不一样呢?其实是商求导的时候是有分子和分母的,只要用两个变量接受分子和分母就好啦:
%% 除法求导
p1 = [2];
p2 = [3 1];
y1 = poly2sym(p1);
y2 = poly2sym(p2);
fprintf('原函数:\ny1 = %s \ny2 = %s\n', y1, y2); % 打印两个原函数
[up, down] = polyder(p1, p2); % 进行商求导,返回[分子, 分母]
resup = poly2sym(up);
resdown = poly2sym(down);
fprintf("导函数:\ny\' = (%s)/(%s)\n", resup, resdown); % 打印导函数
其实这也用到了重载,这一个函数我们用了多次,但其实每次这个函数在参数或返回值上会有不同,很简单好记~
3. 函数
函数这东西必是我们经常要用到的东西,在Matlab中写个函数是非常简单的事情~其实就是新建一个文件写上你所需要调用的函数的代码咯~
我们在这里就拿斐波那契数列求解举例:
function fibo = fibo_clac(n) % 函数定义:返回值 = 函数调用方式
% 函数名:fibo_clac
% 功能:返回斐波那契前n项的数组
% 参数:一个整型参数n,表示需要斐波那契数列前n项
% 返回值:一个n*1的矩阵fibo,包含数列前n项
fibo = zeros(n, 1); % 将返回值定义为一个n行1列的矩阵
%斐波那契数列递推计算
fibo(1) = 1;
fibo(2) = 2;
for i = 3:n
fibo(i) = fibo(i - 1) + fibo(i - 2);
end
return
- 让我们来看看上面的代码,首先第一行就非常非常的重要。这让你的Matlab理解到了这个文件ta是一个函数。并且已知了多个信息:返回值、函数名、参数。
- 接下来是我所写的帮助注释,建议大家也可以写一写,便于使用者理解,也便于自己回忆咯
- 然后就是函数体了,我们在这里使用递推进行计算,略了略了~
4. 数据可视化
4.1. 二维绘图
Matlab中二维图形一般使用plot函数,这个函数可以满足很多的画图功能。
我们先从几个方面对Matlab中的图像进行了解:
- 函数图像了解
- 矩阵图像了解
- plot函数
函数图像:
函数图像一般都是折线图,在图像区间内由多个点连接形成的曲线,我们以函数
y
=
sin
x
y=\sin{x}
y=sinx和
y
=
x
2
+
1
y=x^{2}+1
y=x2+1作为样例,可以简单观察一下图像:
也就是用曲线画出的图像罢了~
矩阵图像:
Matlab中的矩阵也是可以绘制的,那矩阵怎么表示呢?作为一个工程师~我们来打代码试一试:
%% 绘制矩阵
mx = [
3 4 5;
2 5 3;
5 1 7;
]; % 声明矩阵
figure; % 打开绘图窗口
plot(mx); % 画图
title('Martrix');
代码很简单对吧,和我们之前一样,然后用plot打印出来是个什么效果呢?
一看,这不也是折线图吗?我们能从图中发现每一列都是我们矩阵中的每一行,然后相应的每一列都是用折线连接起来的。
所以在默认情况下,矩阵也是用折线图表示的(当然我们通过改变plot函数的参数使图像变成打点)。
然后我们来看我们的plot函数:
我们知道,我们目前的所有图像都是使用plot函数来绘制的,所以我们好好来了解了plot函数就可以画图很多好看的图像了。
首先是关于plot函数中的样式参数:
线符号 | 线型 | 点符号 | 线型 | 颜色符号 | 线型 |
---|---|---|---|---|---|
- | 实线(默认) | + | | | r | 红色 |
– | 虚线 | o | | | g | 绿色 |
: | 点线 | * | | | b | 蓝色 |
-. | 点划线 | x | 相应 | c | 青色 |
< | 样子 | m | 洋红 | ||
> | | | y | 黄色 | ||
^ | | | k | 黑色 | ||
v | | | w | 白色 |
既然我们都已经把表格都列出来了,我们就来画几张试试:
%% 绘制花式图
x = 0: 0.05: 2; % 定制区间
f = sin(8*x); % 定制函数
figure; % 打开绘图窗口
hold on;
subplot(331); % 3*3的窗格画第一个
plot(x, f, "-r"); % 画图
title("红实线");
subplot(332);
plot(x, f, "--g");
title("绿虚线");
subplot(333);
plot(x, f, ":m");
title("洋红点线");
subplot(334);
plot(x, f, "-.k");
title("黑点划线");
subplot(335);
plot(x, f, "^c");
title("用青三角形打点");
subplot(336);
plot(x, f, "-or");
title("红实线&在点上画圆");
subplot(337);
plot(x, f, "--xg");
title('绿虚线&画个叉');
subplot(338);
plot(x, f, ":+m");
title('洋红点线&画个加号');
subplot(339);
plot(x, f, "-.vk");
title('黑点划线&画个倒三角');
根据上面我们就能看出来了,通过排列组合三种符号,就可以得到很多样式的线,可以自己再去试试哦(顺便说一句,参数的符号顺序没啥要求的)。
划线样式——当然不全是为了好看而做出来的,而是为了好进行分辨代表不同东西的线。所以接下来我们就要看看**怎么将一些线画到同一张图里面:**
我们当然可以一条一条给ta画上去:
%% 绘制多线图
x = 0: 0.01: 2; % 定制区间
% 定制函数
f1 = x.^2;
f2 = x;
f3 = sqrt(x);
figure; % 打开绘图窗口
hold on;
plot(x, f1, "-om");
plot(x, f2, "-.*g");
plot(x, f3, ":^b");
hold off;
也可以一起画上去(不过样式只能随机了):
%% 绘制多线图
x = 0: 0.01: 2; % 定制区间
f = [x.^2; x; sqrt(x)];% 定制函数
figure; % 打开绘图窗口
plot(x, f);
我们对这这两个来比较一下:
(注意)在这里有一个点,就是关于plot的参数使用,如果区间x和f翻了会咋样?也就是变成了:
plot(f, x);
我们尝试一下可以得到:
其实也很好发现,就是 x y xy xy的位置错位了而已。
讲一个需要注意的点:
其实在前面我已经说过了,就是我们的曲线其实是靠多点进行绘制的,从我们在点上可以画点符号也可以体现。所以如果要画出光滑曲线应该取尽量多的点。比如我一直使用的 x : 0.01 : 2 x:0.01:2 x:0.01:2,这表示我打了两百个点。
说到打点:
有没有好奇过为啥我的plot函数中为什么一定要加一个范围x呢?可能你觉得就是为了表达区间,没错!你懂了,不错不错。但是你可能没有想过没有这个x会咋样?难道没有这个x就没有区间了吗???
还是一样,作为工程师,我们来敲个代码试试:
%% plot(f)
x = 0: 0.01: 2; % 定制区间
f = x;% 定制函数
figure; % 打开绘图窗口
plot(f);
哎?咋肥事,横坐标怎么变成0~200了?但其实你马上也就能反应过来了,其实我刚刚也讲过了,我打了200个点。所以横坐标现在就是在表示是第几个点了。
所以现在plot函数已经了解到比较透彻了~
那我们再来讲一点**plot的拓展应用吧:**
-
绘制子图(这里可以参考上面绘制花式图的代码)
其实就是是使用subplot创建一个小图,然后确定好位置就好了,这里注意一下,标题放到最后设置就可以了。
备注:其实这里的绘图只是逻辑上进行一个分区罢了,但是没有真的给你规定死,说人话就是你用不同的分区方式一样能画图。
例如:
%% 分区绘图 x = 0: 0.05: 2; % 定制区间 f = sin(8*x); % 定制函数 figure; % 打开绘图窗口 hold on; subplot(311); plot(x, f, "-or"); title("红实线&在点上画圆"); subplot(323); plot(x, f, "--xg"); title('绿虚线&画个叉'); subplot(324); plot(x, f, ":+m"); title('洋红点线&画个加号'); subplot(313); plot(x, f, "-.vk"); title('黑点划线&画个倒三角'); hold off;
所以画图分区上还是很自由的,可以自己试一试。
-
grid设置框线:一般是关闭的,用grid on就可以打开了:
我还是用上面的代码加上了grid on,可以看一看效果
哎,为啥只有上下两个有框线呢?其实是因为grid on的作用域只面对自己的前一个图像,所以我是在上下两个函数的title下面加的grid on。
-
box设置边框:
我还是用第一个案例中的代码,因为看了grid,很容易理解box对作用域也是面对前一个图像,我这回改了中间两个,让我们看一下效果
plot函数的简单介绍到此为止。
但我们知道还有一个东西叫极坐标,最后带一句这玩意儿:
其实极坐标函数polar的用法和plot基本一样,也可以分区操作
%% 极坐标
x = 0: 0.01: 2*pi; % 设置范围
f1 = sin(x);
f2 = cos(x);
f3 = x;
figure; % 创建画板
hold on;
subplot(221);
polar(x, f1);
title('y = sin(x)');
subplot(222);
polar(x, f2);
title('y = cos(x)');
subplot(212);
polar(x, f3);
title('y = tan(x)');
hold off;x
4.2. 三维绘图
三维绘图和二维绘图挺像的,连用的函数都挺像的,三维绘图函数为plot3。
首先我们随便举个例子,我们就来画一个龙卷风吧:
%% Tornado
t = 0: 0.01: 100; % 设置范围
% 列出在每条坐标轴上的函数,在这里x和y可以形成一个逐渐变大的圆
x = t.*sin(t);
y = t.*cos(t);
z = t;
figure;
plot3(x, y, z); % 绘制时放入三个方向的函数
title("Tornado");
所以我们就能理解了,plot3是plot在三维空间上的衍生,可以用来在三维空间里面**绘制曲线**。
然后其实这个也并不是很好理解,因为没有坐标轴,谁知道哪个是哪个,所以我们在这个图像绘制下面加几条语句就好了:
xlabel('x轴');
ylabel('y轴');
zlabel('z轴');
但除了画曲线,我们画曲面的需求也是很大的,我们怎么画曲面呢?在讲解积分的时候曾经使用过一个函数mesh,用于画出一个曲面。
我们在这里随便写一个函数,再来看一下mesh函数绘制图像的效果:
%% 三维绘图
[x, y] = meshgrid(0: 0.01: 5, 0: 0.01: 10); % 设置x,y的点集
z = 3.*x + sqrt(x.*y) + 18.*sin(x.^1.5); % 写出需要绘制的方程
figure;
mesh(x, y, z); % 画图
title("z = ");
xlabel('x轴');
ylabel('y轴');
zlabel('z轴');
看,一张曲面图就被我们画出来啦~
这个时候你会有几个疑惑:
- meshgrid是什么?
- 三维图像在空间里面是怎么绘制的?
这两个问题并不冲突,应该说meshgrid是我们绘制图片中最重要的一个工作,其余的操作也就只是简单的计算而已了。
平常我们怎么探测一个不懂的函数或问题?是靠数学理论么?不!我们是工程师,最简单的方式应该是调试!Matlab为我们提供了一个非常良好的调试环境,首先在工作区中我们就可以看到我们的所有变量和ta的值与形式。在这一次中我们只需要看工作区变量就可以了:
是不是单纯从工作区里面就能看出这个:x复制了y行x的范围,y复制了x行y的范围,变成了两个矩阵。仔细一想,这个操作确实如此,因为我们会发现x和y生成的矩阵覆盖了 x & y x\&y x&y面的每个点,然后我们才能根据这个点去求得与其相应的z轴的高度,就算出来三维地图中的点集 ( x , y , z ) \left(x, y, z\right) (x,y,z)了(然后我们就根据绘制出来的点集画图咯)。顺便就在这里补一张z变量的图吧:
其实从这里我们也能看出来,三维图也是一堆点画出来的。
关于meshgrid的深入了解:
- Meshgrid如果只传入一个参数,说明x,y范围是一样的,就相当于输入了两个一样的参数。
- 但如果传入了三个参数呢?其实很好理解,也就是给z也来了一个参数。
也不难理解,这个时候z的数组里面有多少个数,相当于 x & y x\&y x&y组成的面就有多少层,然后每一次的z值都是所对应的值。看下面的图吧~
%% meshgrid参数改变
[x, y, z] = meshgrid([1 2 3 4], [5 6 7], [8 9]);
最后再讲一个用来**绘制曲面的函数**:
其实我们的mesh在使用的时候是一个一个方格,然后使用这个密集的方格,让我们看起来像是一个曲面(左为放大前,右为放大后):
然后我们再用一个surf函数看一下,用法和mesh是一样的:
%% surf绘图
[x, y] = meshgrid(0: 0.01: 5, 0: 0.01: 10); % 设置x,y的点集
z = 3.*x + sqrt(x.*y) + 18.*sin(x.^1.5); % 写出需要绘制的方程
figure;
surf(x, y, z); % surf画曲面
title('z = ');
% shading interp;
让我们来看一下结果:
看,格子里面有颜色了,这才是真的绘制了图像。别急,我知道你有两个问题:
- 为什么图是黑的啊?
- 注释的那条语句是干啥的?
首先图为什么是黑的?是因为你可以在右边放大的图中可以发现,边框是黑的,我选取了
1
k
×
0.5
k
1k \times 0.5k
1k×0.5k的点集,挺多的,边框都挤在一起了,就没了。所以我们最后一条语句就是用来取消边框的:
我们可以看出来边框没了,现在就是真正是一个曲面了~