此为笔记文档
这里会记下一些没有填上的坑
patch
属性是什么属性是什么
二维和三维的隐函数怎么表示
子级和父级是什么
特殊的数据可视化方法,如heatmap、imagesc
元胞
多文件编程设计
syms
、函数句柄
是什么
里面百度文库的链接需要打开flash再进入
本文使用的Matlab版本是R2019a,可能有的高阶功能不向下兼容,需要自行查阅资料
pdf版建议打开pdf的目录功能,markdown
转pdf
的时候会自动根据标题生成目录
在CSDN的版本由于图片转存太麻烦有的部分原本有图的我就没上传,但是大体不影响阅读,我会留下外网链接,里面将是pdf版
不保证正确!如果发现错误请联系本人,本人将在更新过程中改正!
本人ID:
GitHub:BJTU-ChrisLee
CSDN:BJTU_Chris_Lee
预计之后会持续在CSDN更新,每次更新都会直接改一整篇文章(本文本质是个人的学习笔记),所以请跟进关注
转载之类的请注明出处(个人CSDN的ID等),另外见版权声明
部分
%...
%{
%}
在行末加上 ;
用连行符 ...
,不过字符串似乎不支持多行输入
figure
函数 相关资料
disp
函数可以简单发送信息
clear close
函数 clear close等的用法
pause
类函数 pause类用法
注意只有在操作端左边显示>>
的时候才能输入
如果想要在编写代码的时候就确定一个调试点,可以设置一个keyboard
函数,它允许程序暂停的同时进行值的调整
input
函数:
v1=input('提示性语句:');
%如果想要在input里加上变量的话可以采用下面的方式
v2=input([str1,num2str(v3),str2]);%同样适用于`disp`函数
%即字符串在Matlab中是特殊处理的
%也可以结合disp:
disp([str1,num2str(v3),str]);
v4=input('')%不能缺失 ''
注意,所有的输入和声明赋值操作是一样的,具体见矩阵和字符串中相关内容
从文件输入方法在后面提及
% in 'a.m':
global a;
a=0;
% to use a in 'b.m':
global a;
比如:
plot(x,y,'--gs','LineWidth',2,'MarkerSize',10,'MarkerEdgeColor','b','MarkerFaceColor',[0.5,0.5,0.5]);
(该语句来自于plot
的技术文档)
实际上可以类比C语言读文件时候的'rb'
等控制符,为了易读,将可以更改的命令都做成了字符串,以便很明了地更改属性
,
表示的是一行多个表达式==
、~=
&&
、||
,这两者均有短路机制~
help cmd
查看官方帮助文档(直接声明
A=[1,2,3;2,3,4]
A =
1 2 3
2 3 4
从用户获得输入,注意,输入格式与在代码中输入是一样的
A=input('input A:')
%input
[1,2,3;...
2,3,4]
%end of input
A =
2 3 4
2 4 5
注意,下列方法获得的也是个向量/矩阵,这对理解Matlab怎么操作函数有很重要的意义
A=1:2:5
A =
1 3 5
A=1:3:5
A =
1 4
A=1:3
A =
1 2 3
A=[1:2:5,1:3:5]
A =
1 3 5 1 4
A=[[1:2:5]',[1:3:7]']%'是转置,这里涉及了子矩阵的组合,见‘重构矩阵的方法’一节
A =
1 1
3 4
5 7
A=input('input A:')
%input
1:1:3
%end of input
A =
1 2 3
可以猜测,实际上a:step:b
指的是从a
到b
,步长为step
的向量,也可以知道这种向量和[1,2,3]
这种向量并没有不同之处,这很重要!直接关系能不能正确理解后面的函数!
获得行列数
[rows,cols]=size(A);
szA=size(A);%szA是一个二维行向量
maxrc=length(A);%各个维度的元素数的最大值(2*3*4的三维矩阵即4)
获得维度,注意维度类比是x、y坐标的意思
dimA=ndims(A);
获得非0元素个数
cnt_nzero=nnz(A);
声明矩阵的常用方法
sz是指一个n维向量代表每个维度的元素数
A=ones(sz);%全为1的矩阵
B=zeros(sz);%全为0的矩阵
C=rand(sz);%产生在(0,1)区间均匀分布的随机阵
D=eye(sz);%产生单位阵
E=randn(sz)%产生均值为0,方差为1的标准正态分布随机矩阵
特殊矩阵 见链接中的 二-3
线性索引和坐标的转化
这在位运算中会涉及到,这里只是介绍
摘抄自此
可以使用单个下标A(k) 表示matlab矩阵中的元素,MATLAB不会以矩阵和数组在MATLAB命令行窗口中的显示形状存储矩阵和数组,而是会将矩阵和数组存储为单个元素列。这种单个列由矩阵中的所有列组成,没一列都附加到最后一列。
因此,矩阵
A
A = [2 6 9; 4 2 8; 3 5 1] A = 2 6 9 4 2 8 3 5 1
实际上是以序列形式存储在内存中:
2,4,3,6,2,5,9,8,1
,注意这里是按照先列后行的方式排布矩阵
A
中位于第3行,第2列的元素(值=5)也可以标识为实际存储序列中的第6个元素。要访问此元素,可以使用标准的A(3,2)语法,也可以使用A(6)。如果提供多个下标,Matlab将会基于分配给数组的维度计算存储列的索引。例如,假定
A
之类的二维数组的大小为[d1 d2]
,其中d1
表示数组中的行数,d2
表示列数。如果提供两个表示行-列索引的下标(i, j)
,则偏移为(j-1) * d1 + i
给定表达式
A(3,2)
,MATLAB 会将A
的存储列的偏移计算为(2-1) * 3 + 3
,即6
。从头开始数六个元素即会到达值5
。
主要运用的就是find
函数,所以只对find
函数简要介绍
find(x)
返回一个包含数组 X
中每个非零元素的线形索引的向量
A=[1,0,3;0,4,0;5,0,6]
(find(A))' %转置是为了看起来方便些
ans =
1 3 5 7 9
(find(A<3))'%这里涉及了矩阵的位运算
ans =
1 2 4 6 8
这里也可以看出Matlab优先处理列向量
直接提取法
行的范围:row_a->row_b,列的范围:col_a->col_b
sonA=A(row_a:row_b,col_a:col_b)
如果想要提取全部行/列的话
sonA=A(row_a:row_b,:)%获得了A的row_a->row_b行的全部列
如果不知道具体多少行/列也不想多用变量的话
sonA=A(row_a:row_b,col_a:end)
如果你想的话,甚至可以从row_b->row_a翻转矩阵
son_rev_A=A(row_b:-1:row_a,1:end)
%获得A全部列调转row_a->row_b行之后的矩阵,这里也可以猜出A(:,:)格式的本质是什么
还记得吗,a:step:b
实际上是一种向量,所以下面的方法获得矩阵也是可以的
这里pos
使用的是线性索引
A=[1,0,3;0,4,0;5,0,6];
pos=[1,2;3,4]
A(pos)
ans =
1 0
5 0
pos=[1:2:3;2,5]
A(pos)
ans =
1 5
0 4
可以猜测直接提取法的本质:
A(B)
将返回与B
大小一致的矩阵,其中的元素为B
上每一个位置对应的线性索引对应的A
的值
reshape
函数
目测不是很好用,如果上面的方法无法满足需求时可以 点击这个链接 了解具体怎么用,当然,也可以help reshape
组合矩阵法
获得A,B构成的矩阵,这里的例子要求A的行数与B的行数一致(与数学上的分块的要求一样)
C=[A(1:2,1),B(1:2,:)]
只记录几个常用的,其他如求上三角、求转置、翻转等 参阅这个链接
取整函数fix
ceil
floor
%fix将X的每个元素朝零方向四舍五入为最近的整数
A=fix(10*rand(1,10));%产生1*10的每个元素均为0-9之间随机整数的矩阵
%ceil将X的每个元素四舍五入到大于或等于该元素的最接近整数
%floor将X的每个元素四舍五入到小于或等于该元素的最接近整数
计算矩阵的秩/行列式/特征值/迹/逆等
r=rank(A);%矩阵的秩
d=det(A);%矩阵的行列式
v=eig(A);%矩阵的特征值,这里的v是一个列向量
t=trace(A);%矩阵的迹,这里A必须是方阵
A=inv(A);%矩阵的逆
需要查找其他的求值函数(如求约化阶梯阵)时可以百度和help cmd
求矩阵的转置
B=A'
B=A.'
两者的在涉及复数时的区别请参阅help '
求对角线元素
与求迹不同,这里不需要A
是方阵,会逐个取 A(i,i)
元素
B=diag(A)
注意,matlab几乎一切皆矩阵,所以矩阵的运算会伴随使用Matlab的全过程,一定要思考每一个函数与矩阵是否有关系
以A=[1,2,3;4,5,6;7,8,9]
为例,不考虑多维数组,需要讨论多维数组的情况请help cmd
sum和max
对于向量,[num,index]=max(A)
返回元素最大值和下标
%A=[1,2,3,4,5]
[num,index]=max(A(1:end,1))
num =
1
index =
1
对于矩阵,直接看代码
%A=[1,2,3;4,5,2;3,3,4]
[y,u]=max(A)
y =
4 5 4
u =
2 2 3
[y,u]=max(A,2)
对于矩阵,sum(A)
将返回包含每列总和的行向量
sum(A)
ans =
12 15 18
如果想要部分区域的,可以提取矩阵再求和
sum(A(1:2,2:end))
ans =
7 9
如果想要全部的,可以sum(sum())
sum(A(1:2,2:end))
ans =
16
实际上是一个复合过程
mean求均值
对于向量,mean(A)
返回元素均值
mean(A(1:end,1))
ans =
4
对于矩阵,mean(A)
返回包含每列均值的行向量
这里不再demo,与sum
函数类似
这里有很多复杂的小点,比如很多数学上不支持的运算是有结果的,遇到疑问请help cmd
以 A=[1,1,2;2,3,4;3,4,5]
和 B=[-1,-1,2;1,2,3;2,3,4]
为例
计算A*B
注意要满足矩阵相乘的法则,即A_rows==B_cols
A*B
ans =
4 7 13
9 16 29
11 20 38
计算A-B
这里A
、B
维度不同也没事,具体为什么请help -
A-B
ans =
2 2 0
1 1 1
1 1 1
A(1:2,1)-B(1,1:2)
ans =
2 2
3 3
注意,也可以对部分元素相减的
A(1:3)=B(1:3)-1%这里用的是线性索引
A =
-2 1 2
0 3 4
1 4 5
求解线性方程组x*A=B
的x
注意A
、B
的列数要一致
A/B(1,1:end)
ans =
0.3333
0.5000
0.5000
求解A
、B
中元素逐个相除的结果
注意数值输入A
和B
必须具有相同的大小或兼容的大小,例如,A
是 M*N
矩阵,B
是标量或 1*N
行向量,具体请help ./
A./B
ans =
-1.0000 -1.0000 1.0000
2.0000 1.5000 1.3333
1.5000 1.3333 1.2500
A
ans =
1 1 2
2 3 4
3 4 5
B(1,1:end)
ans =
-1 -1 2
A./B(1,1:end)
ans =
-1.0000 -1.0000 1.0000
-2.0000 -3.0000 2.0000
-3.0000 -4.0000 2.5000
其他类型除法可以help /
后根据提示的内容查阅
矩阵的逻辑运算
注意,没有要求行列相同,返回的都是logical数组
下面的讨论针对A
、B
矩阵
A=[1,2,3;0,4,0;5,0,6]
B=[0,1,0;3,3,5;0,6,4]
按位取且:都不为0则返回1
A&B
ans =
0 1 0
0 1 0
0 0 1
按位取或:只要有一个不为0就取1
A|B
ans =
1 1 1
1 1 1
1 1 1
按位逐个取异或:均为0/均不为0-取0,一个为0一个不为0-取1
xor(A,B)
ans =
1 0 1
1 0 1
1 1 0
按位比较:即矩阵的大小关系是指各个元素的大小关系
A<3
ans =
1 1 0
1 0 1
0 1 0
其他的逻辑运算可以help &
来查找,关于logical数组也直接help logical
了解,不详细介绍
在MATLAB中,字符串是用单撇号括起来的字符序列。MATLAB将字符串当作一个行向量,每个元素对应一个字符,其标识方法和数值向量相同。也可以建立多行字符串矩阵。字符串是以ASCII码形式存储的。abs和double函数都可以用来获取字符串矩阵所对应的ASCII码数值矩阵。相反,char函数可以把ASCII码矩阵转换为字符串矩阵。与字符串有关的另一个重要函数是eval,其调用格式为: eval_r(t) 其中t为字符串。它的作用是把字符串的内容作为对应的MATLAB语句来执行
以上引用自 链接文章第五点 ,下就常用函数和基础功能进行介绍
声明和从用户获得输入,与矩阵的类似,不再详细解释
str='this is test string'
str=input('input str:')
%input
'This Is Test Too'
%end of input
str =
'This Is Test Too'
可以通过num2str
函数将数组转化成字符串:
num2str(100)
ans =
'2'
允许申请多维字符串
strC=['Hello';'World']
ans =
'Hello'
'World'
num2str([1,2;3,4])
ans =
'1 2'
'3 4'
注意将字符串看成矩阵
使用小串和变量构建大串
strA='Hello';
strB='World';
[strA,num2str([1,2,3]),strB]
ans =
'Hello1 2 3World'
%很蹩脚的例子,不过很能反应特点
也可以将多维字符串连接起来
[[strA;strB],num2str([1,2;3,4]),[strA;strB]]
ans =
'Hello1 2Hello'
'World3 4World'
获得指定下标构成的子串
strA(1:2:5)%用的是线性索引
ans =
'Hlo'
当然也可以针对多维字符串取下标,将它想象成矩阵就行,但是要注意用的是线性索引
strC=[strA;strB];
strC([1:3:5;2:2:5])
ans =
'Ho'
'Wo'
判断是否相等
strcmp(s1,s2)
,相等返回1,不相等返回0。另外注意这与C语言中的strcmp
判断字典序不一样
查找子串
strfind(str,pattern)
,在str
中找pattern
,返回的是下标索引,经过测试应该不能在多维字符串中搜索
替换子串
newStr = strrep(str,old,new)
,将 str 中出现的所有 old 都替换为 new
eval
函数可以执行字符串中的命令
其他的函数参见:前人总结的链接
以str='This Is Test Too'
为例
获得反串
str(1,end:-1:1)
ans =
'ooT tseT sI sihT'
从中,结合前面 ‘重构矩阵的方法’ 可以看出,字符串就是一个1*N
的向量,这点与C语言处理方式很像
查找大写字母并转换成小写
线性索引:字符串(1*N
向量)中的线形索引就是指下标(从1开始,与C语言不通)
字符串的逻辑运算:与矩阵一样,因为实际上字符串就是1*length
的矩阵
str=='T'
ans =
1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0
find
函数
在help find
中提到,find(x)
返回一个数组 X 中每个非零元素的线性索引的向量,与矩阵中的类似
由于根据help find
- 如果
X
为向量,则find
返回方向与X
相同的向量- 如果
X
为多维数组,则find
返回由结果的线性索引组成的列向量- 如果
X
不包含非零元素或为空,则find
返回一个空数组
在字符串处理中,find(x)
将返回一个行向量
find(str=='T')
ans =
1 9 14
在上一点中可以看到,只有这三个线性索引对应位置str
的值是‘T’
所以想要找到str
中的大写字母下标就很简单了
pos=find(str>='A' & str<='Z')%这里的&就是逐位取和了
pos =
1 6 9 14
解释一下,这里实际上发生的是:
str>='A'
和str<='Z'
分别操作,返回两个logical
向量find
函数找到新的向量中的1并且返回下标向量给pos
转换
这里实际上是部分元素减法,与部分矩阵减法是一样的
str(pos)=str(pos)-'A'+'a' %Matlab中用的也是ASCII码
xlsread(filename)
,涉及提取部分/涉及中文/等问题时,help xlsread
importdata(filename)
,同样,涉及问题时help inportdata
,值得注意的是,从txt中提取文件时可以指定分隔符,也可以由系统猜测(并输出)分隔符xlswrite(filename,mat)
,使用时help xlswrite
importdata
,会产生一个cell
属性的textdata
和一个double
的mat
table
属性:这里有详细介绍xlswrite
,具体怎么做help xlswrite
,注意有时候会拉出.csv文件,即使已经有且指定了.xlsx文件了,并且会覆盖原文件plot
的使用和基础知识即给出点的数据,怎么用坐标轴的形式显示出来
运用plot
画出简单函数
以下面一连串代码为例,将会实现
x
和y
向量来表示函数取点hold on
来在一张图上画函数x
、y
坐标定义x
、y
,在Matlab中的函数实际上都是用点画出来的
注意,这里sin(x)
cos(x)
tan(x)
得到的实际上是一个矩阵,矩阵元素逐一相乘必须用.*
而画图实际上就是把x
对应y
变成点在图上画出
x1=linespace(-2*pi,2*pi);
y1=sin(x).*cos(x);
x2=linespace(-2*pi,2*pi);
y2=sin(x).*tan(x);
一个函数画两条线,这里的fg1
是一个line
数据
如果想要知道更多关于fg1
可以设置的东西,如每隔多少数据标点,颜色,打星等等,可以help line
点击line属性
解决
fg1=plot(x1,y1,x2,y2)
fg1(1).LineWidth=2;
fg1(2).Marker='*';
使用下面的语句也可以达到同样的效果,但是注意,需要标注时plot
只能画一条线
fg1=plot(x1,y1,'LineWidth',2)
hold on;
fg2=plot(x2,y2,'Marker','*')
hold off;%别忘了hold off
下面的函数可以标注图,经测试,对以上两种方法都适用
xlabel('x轴')
ylabel('y轴')
title('TEST')
grid on;%显示单元格
如果想要画分图的话,需要用到subplot
函数,以下案例来自help plot
ax1 = subplot(2,1,1);% top subplot
plot(ax1,x1,y1)
title(ax1,'TOP')
ylabel(ax1,'sinx*cosx')
ax2 = subplot(2,1,2);% bottom subplot
plot(ax2,x2,y2)
title(ax2,'Bottom Subplot')
ylabel(ax2,'sinx*tanx')
当然,也可以通过获得plot
返回值的方法改变曲线特性,这里就不赘述了
参数方程画法
这里选择圆 $(x-1)2+(y-3)2=4 $ 来做图
圆的方程可以写成:$\begin{cases}x=2\cos t\ +1&\ y=2\sin t\ +3&\end{cases} $ ,根据plot实际上就是一个个点连起来的思想,可以如下编写:
t=linspace(0,2*pi);
x=2*cos(t)+1;
y=2*sin(t)+3;
plot(x,y)
画出来的圆有点扁,可以通过axis equal
让沿每个坐标方向使用相等的数据单位
分段函数画法
可以利用hold on
来画
例如,如果要画$\begin{cases}e^{x}&-3 理论上可以把 后面会介绍更好的画法x1=linspace(-3,0);
y1=exp(x1);%注意matlab没有自然对数e,如果真的需要请用exp(1)表示
plot(x1,y1,'b')
hold on;
x2=linspace(0,3);
y2=cos(x2);
plot(x2,y2,'b')
hold off;
grid on;
y
分成两份对应,不过过于复杂了就不演示了
奇奇怪怪的技巧
plot([x1;x2],[y1;y2])
可以画出类似直方图的感觉plot
类函数fplot
精确画一元函数
以 $y=x\sin \frac{1}{x} $ 为例
如果plot
的话是不好取点的,因为这个函数在 $\lim_{x\rightarrow 0} $ 的时候是一个震荡函数,会丢失很多细节,这时使用自带的fplot
函数就很有帮助了
y=@(x)sin(1./x);
fplot(y,[minx,miny])
需要控制更多内容,如相对误差、线形
当然用fplot
画参数方程也是可以的
x=@(t)cos(3*t);
y=@(t)sin(2*t);
fplot(x,y,[tmin,tmax])%对于这个曲线建议设成[0,2*pi]
也可以画分段函数,还是以$\begin{cases}e^{x}&-3fplot(@(x) exp(x),[-3 0],'b')
hold on
fplot(@(x) cos(x),[0 3],'b')
hold off
grid on
ezplot
不推荐用的函数
在help ezplot
界面中说
(不推荐)易用的函数绘图函数
那就简单看一下吧。。。
画隐函数,以 x 2 − y 4 = 0 x^{2}-y^{4}=0 x2−y4=0为例
ezplot('x^2-y^4')
不太懂为什么不建议使用
注意的点:
如果使用了hold on
命令,可以在同一张图中绘不同坐标系的图
polar
绘制极坐标系下的图
绘制$r=e^{\sin t}+2\sin 4t-\left( \cos \frac{t}{5} \right)^{6} $图像
t=linspace(0,24*pi,100);%这里maxt越大图像越诡异。。。不管了
r=exp(sin(t))+2*sin(4*t)-(cos(t/5)).^6;
ax1=subplot(2,1,1);
ax2=subplot(2,1,2);
plot(ax1,t,r);
polar(ax2,t,r)
这里也可以利用[x,y]=pol2cart(t,r)
画出在直角坐标系下的图
[x,y]=pol2cart(t,r);
plot(x,y)
semilogy
、semologx
和loglog
绘制对数坐标的图
和plot
几乎一样,不再赘述,有需要help cmd
plotyy
双y坐标绘图
与plot
还是基本上一样,有需要help plotyy
双坐标轴绘图
直接参考链接
图源自《matlab:从入门到精通》
一般使用meshgrid
去分割点,与linspace
作用一致(虽然实际上可以不用linspace
去分割)。根据help meshgrid
的提示,实际上[X,Y] = meshgrid(v)
作用是X
是一个矩阵,每一行是V
的一个副本;Y
也是一个矩阵,每一列是 V
的一个副本
这么分布可以让其他元素和x
、y
一一对应,在后面一个例子中会体现这么做的用处
常用的有四种:mesh
surf
surfc
surfl
参考链接
直接看图:
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;%eps是一个精度范围,详情help eps
Z = sin(R)./R;
ax1=subplot(2,2,1);
ax2=subplot(2,2,2);
ax3=subplot(2,2,3);
ax4=subplot(2,2,4);
mesh(ax1,X,Y,Z);
surf(ax2,X,Y,Z);
surfc(ax3,X,Y,Z);
surfl(ax4,X,Y,Z);
title(ax1,'mesh');
title(ax2,'surf');
title(ax3,'surfc');
title(ax4,'surfl');
具体需求请help cmd
,另外注意可以通过下面行为产生无颜色的图像
%紧接着上面的代码
shading interp;
colormap(gray);
另外对于surfl
:(命令中的’l’表示这是一个光照表面 lighted surface)命令显示三维光照物体的表面,可以使用这个命令产生没有线条的三维图像
实际上这里的函数不是万能的,比如复杂的无法用$z=f\left( x,y\right) $表示的三维图形就不好表示了,具体的处理方法见后面的高级可视化
另外,这里使用的都是绘面,而plot3实际上是绘制线的!
实际上在上个三维绘图的比较中就可以看到子图的操作方法了,这里再拓展一些,探究一下Matlab到底怎么实现控制图的信息的
subplot
包含了什么,axes
是什么上面的比较代码中,我们看到先声明了ax=subplot(2,2,1);
,这里解释一下:
subplot(m,n,p)
的用法:将当前图窗划分为 m*n
网格,并在 p 位置创建笛卡尔坐标区(这里分图的顺序是先行后列)ax
的类型Axes
有什么用:Axes
属性可控制 Axes
对象的外观和行为。通过更改属性值,您可以修改坐标区的特定方面,例如:ax.Title.String = 'My Title';
ax.Title.FontWeight = 'normal';
分别改变了标题的内容和字体粗细(在help Axes
中说到了如何用两行字符命名,可以查阅)关于画子图的问题,见链接
推荐使用ax.
的方式访问以及更改,具体到需要改变什么的时候可以help axes
点击Axes属性
来了解
有时候有点函数也可以输入ax
以达到指定在某个图中进行某功能的目的,例如help legend
中的“在特定坐标区上添加图例”
实际上所有的图都是通过改变Axes属性
来改变图的内容的,那在单个图的标注中为什么没有看到ax这种东西出现呢?(实际上只有执行ax=gca;
才能看到带Axes属性
的变量)因为title
类似的函数默认针对gca
(当前图窗的当前坐标区或图,通常是最后创建的图窗或用鼠标点击的最后一个图窗)操作,所以才不需要ax
辅助。但是在子图的标注中如果通过gca
就全乱套了,所以一般是通过ax
控制的,也就是上面的比较代码中显示的那样
所以如果不确定,执行ax=gca
来改变单图信息,以和多图情况统一
填充函数:fill(x,y,c);
执行了感受下效果就行,具体要求help fill
x=linspace(-2*pi,2*pi);
y=x.*sin(x);
fill(ax);
图中标注函数:text(x,y,'str')
同样,知道有这么个东西就行,用的时候直接help text
查询可以更改的值
不过要注意,建议使用text
的返回值,不然可能没地方改内容
%接上代码
text(0,0,'<-----zero','Rotation',90);
另外gtext
可以直接用鼠标标注
增加图例的函数:legend()
具体参照技术文档help legend
help plot
可以帮助了解更多细节
待填坑
目前只找到这么多,如果以后发现更多的可以更新
只会指明有哪些函数,并贴出示意图,具体怎么操作请help cmd
另外实际上Matlab绘图页已经给出了一些图的样子了,可以用那个做参考
bar
、bar3
area
pie
Y=[45 6 8;7 4 7;6 25 4;7 5 8;9 9 4;2 6 8];
%下面两个语句选择一个执行
subplot(2,2,1)
bar(Y)
title('图1')
subplot(2,2,2)
bar3(Y), title('图2')
subplot(2,2,3)
bar(Y,2.5)
title('图3')
subplot(2 , 2, 4)
bar(Y,'stack'),title('图4')
area(Y)
grid on
colormap summer
set(gca,'layer','top')
title('面积图')
柱状图:hist
(直角坐标下)rose
(柱坐标下)
误差棒图:errorbar
火柴杆图:stem
、stem3
阶梯图:stairs
罗盘图:compass
羽毛图:feather
箭头图:quiver
、quiver3
sym
属性来源:
CSDNdalao总结的匿名函数的相关
CSDNdalao总结的syms的相关
顺便,说一下英文
funtion handle
sym
类型表示的函数以及匿名函数的区别:
实际上sym
是一种可以看作字符串表示的函数,但是内部的变量需要先命名,并且不采用矩阵运算符表示
syms x y
a=1;
z=a*(x+y)
%{
z =
x + y
%}
ezplot(z);
显示的是 x + y = 0 x+y=0 x+y=0的图像,即使后来clear x
、clear a
也不会失效,所以和x
、y
和a
本身没关系
而匿名函数则可以看作一个function
,输入就在@()
的括号里面
y=@(x)integral(@(t)sin(t),0,x);
fplot(y)
y(pi)
%{
ans =
2.0000
同时显示图像
%}
这里 y = ∫ 0 x s i n t d t y=\int_{0}^{x}sint\rm{dt} y=∫0xsintdt,使用了两个函数句柄,实际上很多Matlab的函数都要求输入函数句柄,可以理解成C语言中的传函数指针进另一个函数
gca
见模块“图的标注-怎么改变图中的信息”
axis equal
使笛卡尔坐标系的gca
坐标轴相等
grid on
使gca
显示坐标区间
intergral(@()f,a,b)
表示 ∫ a b f d t \int_{a}^{b}f\rm{dt} ∫abfdt
int(y,a,b)
和上个基本一样,不同的是这里的y是一个sym
类型的
这里主要是为了作者写作方便
引用:
CSDN:Latex 箭头、下标、符号上下写文字、正方形和三角形
CSDN:Latex 符号总结(各种箭头符号)
简书:Latex常用符号
百度经验:Latex常用数学符号输入方法
下标 x 0 x_{0} x0:x_{0}
上标 x y x^{y} xy:x^{y}
积分符号 ∫ x x + 1 \int_{x}^{x+1} ∫xx+1:\int_{x}^{x+1}
,实际就是\int
和上下标
一重闭合积分 ∮ \oint ∮:\oint
二、三重闭合积分:需要对应的支持。。。暂时就不管了吧
\def\ooint{{\bigcirc}\kern-11.5pt{\int}\kern-6.5pt{\int}}
\def\oooint{{\bigcirc}\kern-12.3pt{\int}\kern-7pt{\int}\kern-7pt{\int}}
\ooint
\\
\oooint
见链接:简书转载
分数 x y \frac{x}{y} yx:\frac{x}{y}
无穷 ∞ \infty ∞:\infty
更号下 x \sqrt{x} x:\sqrt{x}
n次方下 x n \sqrt[n]{x} nx:\sqrt[n]{x}
趋近于 x → 0 x\to0 x→0:x\to0
极限 lim x → + ∞ \lim_{x\to+\infty} limx→+∞:\lim_{x\to+\infty}
连加 ∑ i = 1 n \sum\limits_{i=1}\limits^{n} i=1∑n:\sum\limits_{i=1}\limits^{n}
对于其他上下有算式的符号同理
微分 d x \rm{d}x dx:\rm{d}x
,这里直接dx
也没问题。。。实际上是一个调整为正体的函数
大括号 { x a y b \begin{cases} x&a &\\ y&b &\end{cases} {xyab:\begin{cases} x&a &\\ y&b &\end{cases}
,这里的cases
是排版关键字
小写希腊字母 α . . . \alpha... α...:\alpha
,alpha可以是任何希腊小写字母的英文,见附录
大写希腊字母 Γ . . . \Gamma... Γ...:\Gamma
,Gamma可以是任何希腊大写字母英文,见附录
换行:\\
空格:\
(里面有个空格)
向量 x ⃗ \vec x x:\vec x
特殊乘除 ⋅ × ÷ \ \ \cdot \ \times\ \div ⋅ × ÷ :点乘\cdot
,叉乘\times
,除号\div
连等号KaTeX parse error: No such environment: align at position 7: \begin{̲a̲l̲i̲g̲n̲}̲x&=y*2\\&=2y \e…:\begin{align}x&=y*2\\&=2y \end{align}
特殊需求:简书链接
其他对齐了解:来自CSDN
三角 △ \triangle △:\triangle
梯度 ∇ \nabla ∇:\nabla
实际上l=polar(theta,rho)
中的polar
函数返回的是line属性
,如果输入gca
的话可以看到一个叫做PolarAxes
的东西,也就是所谓极坐标的axes
(前面提过),关闭窗口之前输入会显示l
的信息,关闭窗口之后再输入l
会显示已删除的对象
。实际上函数都是有返回值的,但是本文档前期都不会关注返回值和属性这俩复杂的东西,只要知道如果需要(比如改变图形样式)可以想办法获得这个返回值(也有可能是一个窗口)即可,在涉及到可能实用的地方会专门提及
主要还是百度+help cmd
来的。。。
log
exp
NaN
:不是一个数,在积分中可以认为出错了,比如syms x;int(1/x,-1,1)
就会返回NaN
,因为这个函数的积分结果是无的(千万别看偶函数说值为0!)
inf
:无穷,比如输入syms x;int(exp((-1)*x^2),0,inf)
就可以返回pi^(1/2)/2
这里实际上就是说: ∫ 0 ∞ e − x 2 d x = π 2 \int_{0}^{\infty}e^{-x^2}\mathrm{d}x=\frac{\sqrt{\pi}}{2} ∫0∞e−x2dx=2π(这个可以通过双重积分转极坐标系下求解)
一般涉及积不出来的函数的时候会遇到,见下文链接
常见积不出来的函数
logint
:对数积分定义: ∫ 0 x 1 l n ( x ) d x \int_{0}^{x}\frac{1}{ln(x)} dx ∫0xln(x)1dx
出处:
syms x;
y=x/log(x);
int(y,2,3)
部分来源:
- 一、二重定积分
- 含变量的积分
一重int
法
直接举例:
syms x;
y=log(sqrt(2*x-x^2)/x+sqrt(1+(2*x-x^2)/x^2));
int(y,0,2)%integration
注意这里使用的是ezplot
画函数的方法,所以y
的表达式里面不需要使用矩阵的乘法
输出结果:
ans =
2
但是如果输入下列函数
syms x;
y=x/log(x);
int(y,2,3);
回出现下面结果
ans =
logint(9) - logint(4)
这里的logint
是一个函数,见前的特殊函数
如果把输入的范围变成 ( 0 , 2 ) (0,2) (0,2)就会返回NaN
,应该是无极限(不是无穷)的意思
实际上如果去积分的话会发现这里跨了一个函数趋向无穷的点,是不可积点
一重integral
法
直接举例:
integral(@(x)sin(x),-pi/2,pi)
这里的@(x)
可以称为函数句柄
,在报错中经常会出现
二重integral2
计算定上下限函数
还是直接举例
f=@(x,y)exp(-x.^2/2).*sin(x.^2+y);
I=dblquad(f,-2,2,-1,1)
返回的结果为:
I =
1.5745
注意到dblquad
底下抛了一个warning,说建议使用integral2
。。。那就用吧
实际上类比integral3
就是三重积分
变上限函数的表示和求解
变上限函数可以用syms
和int
去定义
syms x;
y=int(sin(x),x,0,x);%这里可以查出y是一个syms变量,很神奇
int(y,x,0,pi/2)%返回结果pi/2 - 1,实际上就是对1-cos(x)求定积分
ezplot(x,y)%画出图
二重双int
二重转二次
上述intergral
函数不能求 ∫ − 1 1 d x ∫ − 1 − x 2 1 − x 2 d y \int_{-1}^{1}\rm{d}x\int_{-\sqrt{1-x^2}}^{\sqrt{1-x^2}}\rm{d}y ∫−11dx∫−1−x21−x2dy这种函数(提示信息:A 和 B 必须为浮点标量。
),所以可以用一些笨方法:双int
syms x y;
iy=int(1,y,-sqrt(1-x^2),sqrt(1-x^2));%这里第二个y表示对谁积分。。。吧
int(iy,x,-1,1)
fplot
匿名函数型使用fplot
表示一般函数
y=@(x)sin(x)./x;
fplot(y);
grid on;
使用fplot
表示参数函数
星形线 x 2 3 + y 2 3 = 1 x^{\frac{2}{3}}+y^{\frac{2}{3}}=1 x32+y32=1
x=@(t)(cos(t)).^3;
y=@(t)(sin(t)).^3;
fplot(x,y);
axis equal
grid on
最速降线 { x = θ − s i n ( θ ) y = 1 − c o s ( θ ) \begin{cases} x=\theta-sin(\theta) &\\ y=1-cos(\theta) &\end{cases} {x=θ−sin(θ)y=1−cos(θ)
x=@(t)t-sin(t);
y=@(t)1-cos(t);
fplot(x,y,[0,2*pi]);
grid on
axis equal
使用fplot
表示隐函数
不用参数方程是不可行的,见来自iLoveMATLAB的解释
至于怎么调节范围之类的,help fplot
了解
fimplicit
匿名函数表示隐函数型表示方法:
fimplicit(@(x,y)f,[minn,maxn])
在x、y上的 [ m a x n , m i n n ] [maxn,minn] [maxn,minn]区间内画 f = 0 f=0 f=0的曲线
举例
双纽线 ( x 2 + y 2 ) 2 = ( x 2 + y 2 ) (x^2+y^2)^2=(x^2+y^2) (x2+y2)2=(x2+y2)(当然实际上双纽线可以用极坐标画,也不是非用隐函数就是了)
fimplicit(@(x,y)((x.^2+y.^2).^2-(x.^2-y.^2)));
grid on
当然也有其他办法
syms x y;
fimplicit(((x.^2+y.^2).^2-(x.^2-y.^2)));
grid on
关于怎么控制范围之类的,help fimplicit
了解
前面使用过polar
画极坐标下的图,但是根据Matlab的help polar
中的提示,不建议使用polar
而建议使用polarplot
来绘图,所以下面以polarplot
为主讲~~(当然实际上我并没有看出两者的区别)~~
目前没有找到类似subplot
的函数,如果需要画分图的话可以转到直角坐标系画,使用的函数为pol2cart
,很简单,注意可以用在柱坐标系中,具体不介绍了(使用时如果不知道怎么用请help pol2cart
)
目前找到的资料看似乎只有使用最原始的方法画图——也就是找 θ \theta θ和对应的 ρ \rho ρ,然后映射在坐标上
只举例,不难理解就不管了
以花瓣图 ρ = s i n ( 3 θ ) \rho=sin(3\theta) ρ=sin(3θ)举例
theta=linspace(0,2*pi);
rho=sin(3*theta);
l=polarplot(theta,rho);
l.Color='r';l.Marker='*';l.MarkerSize=2;
或者试一试心型线 ρ = 1 − s i n ( θ ) \rho=1-sin(\theta) ρ=1−sin(θ)
theta=linspace(0,2*pi);
rho=1-sin(theta);
l=polarplot(theta,rho);
l.Color='r';
注意,这里介绍的都是能用参数表示的线,实际上表示线还可以使用相交平面的方法,这种方法暂时不在本块讨论
以螺线 { x = c o s ( v ) y = s i n ( v ) z = v \begin{cases} x=cos(v)\\ y=sin(v) \\ z=v \end{cases} ⎩⎪⎨⎪⎧x=cos(v)y=sin(v)z=v为例:
t = 0:pi/50:10*pi;
st = sin(t);
ct = cos(t);
plot3(st,ct,t)
看得出来,还是和plot
一样的味道,本质是画三维点,然后连成线,有的其他功能help plot3
(如标点、改变线宽颜色之类的)
再画几个好玩的
圆锥螺线 { x = t c o s ( t ) y = t s i n ( t ) z = t \begin{cases}x=tcos(t)\\y=tsin(t)\\z=t\end{cases} ⎩⎪⎨⎪⎧x=tcos(t)y=tsin(t)z=t:
t = 0:pi/50:10*pi;
st = t.*sin(t);
ct = t.*cos(t);
plot3(st,ct,t)
上升的三叶玫瑰线(三叶玫瑰线: ρ = s i n ( 3 θ ) \rho=sin(3\theta) ρ=sin(3θ)) { x = s i n ( 3 θ ) c o s ( θ ) y = s i n ( 3 θ ) s i n ( θ ) z = θ \begin{cases}x=sin(3\theta)cos(\theta)\\y=sin(3\theta)sin(\theta)\\z=\theta\end{cases} ⎩⎪⎨⎪⎧x=sin(3θ)cos(θ)y=sin(3θ)sin(θ)z=θ:
%使用plot3
t = 0:pi/100:10*pi;%这里间距不够小的话可能出现断线
z=t/5;
x = sin(3*z).*cos(z);
y = sin(3*z).*sin(z);
plot3(x,y,z)
实际上使用fplot3
也可以表示类似函数,注意这里的fplot3
不再能使用@(x,y)f(x,y)
了
以下函数来自help fplot3
,表示的是: { x = t y = t / 2 z = s i n ( 6 t ) \begin{cases}x=t\\y=t/2\\z=sin(6t)\end{cases} ⎩⎪⎨⎪⎧x=ty=t/2z=sin(6t),实际上可以看成在 x = 2 y x=2y x=2y平面上画图,神了。。。
xt = @(t)t;
yt = @(t)t/2;
zt = @(t)sin(6*t);
fplot3(xt,yt,zt,[-2*pi 2*pi])
fsurf
匿名函数画可用 z = f ( x , y ) z=f(x,y) z=f(x,y)表示的面前面介绍的是使用meshgrid
和surf
画面,下面介绍利用funtion handle
和fsurf
画面的方法
有时候使用ezsurf
系统会抛一个提示,即建议使用fsurf
,不过本质上就是一个syms
一个handle function
的区别,不是大问题
使用fsurf
表示 z = f ( x , y ) z=f(x,y) z=f(x,y)类
使用马鞍面 z = x 2 − y 2 2 z=x^{2}-\frac{y^{2}}{2} z=x2−2y2举例
funz=@(x,y)(x.^2)-(y.^2)./2
fsurf(funz)
%终端会输出funz是一个function handle,并且显示马鞍面
使用fsurs
表示参数函数(画线型和画面型)
先说画线型,也就是只有一个参数的参数方程
以螺线 { x = c o s ( v ) y = s i n ( v ) z = v \begin{cases} x=cos(v)\\ y=sin(v) \\ z=v \end{cases} ⎩⎪⎨⎪⎧x=cos(v)y=sin(v)z=v为例,注意fsurf
也可以画线,只不过这个计算时间有亿点长
x=@(v)cos(v)
y=@(v)sin(v)
z=@(v)v
fsurf(x,y,z)
面也可以用fsurf
表示
以螺旋面 { x = u c o s ( v ) y = u s i n ( v ) z = v \begin{cases} x=ucos(v) \\ y=usin(v) \\z=v \end{cases} ⎩⎪⎨⎪⎧x=ucos(v)y=usin(v)z=v为例
x=@(u,v)u.*cos(v)
y=@(u,v)u.*sin(v)
z=@(u,v)v
fsurf(x,y,z)
同样,不能用来画隐函数,但是遗憾的是,Matlab没有支持画三维隐函数的函数,ezmesh
和ezsurf
都只能画显函数,也就是类似 z = f ( x , y ) z=f(x,y) z=f(x,y)的函数(可以见help ezmesh
中的说明来了解)。理论上可以用另一种方式表示包含隐函数的三维图形,但是下面会先介绍一些其他类型的画3D图形的函数
还有一点,由于默认是 z = f ( x , y ) z=f(x,y) z=f(x,y),无法画 x = 1 x=1 x=1或者 x + y = 1 x+y=1 x+y=1这类的图像,可以使用后面介绍的ezimplot3
来画
代码来源
原理介绍
function drawsphere(a,b,c,R)
%% 绘制球面
% 以(a,b,c)为球心,R为半径
% 生成数据
[x,y,z] = sphere(20);
% 调整半径
x = R*x;
y = R*y;
z = R*z;
% 调整球心
x = x+a;
y = y+b;
z = z+c;
% 使用mesh绘制
figure;
axis equal;
mesh(x,y,z);
% 使用surf绘制
figure;
axis equal;
surf(x,y,z);
end
主程序调用drawsphere(1,2,3,2);
这种即可,这里也可以改变图形变成画椭球,原理一样就不介绍了
方法和函数来源
ezimplot3
函数如引用链接里说的,已经有dalao做出了函数来演示,函数名称为ezimplot3
,链接下载
输入参数:
ezimplot3一共有三种参数调用方式:
ezimplot3(f)
画函数 f ( X , Y , Z ) = 0 f(X,Y,Z)= 0 f(X,Y,Z)=0在 − 2 π < X < 2 π , − 2 π < Y < 2 π , − 2 p i < Z < 2 π -2\pi< X < 2\pi, -2\pi < Y < 2\pi, -2\ pi < Z < 2\pi −2π<X<2π,−2π<Y<2π,−2 pi<Z<2π上的图形ezimplot3(f, [A,B])
画函数 f ( X , Y , Z ) = 0 f(X,Y,Z)= 0 f(X,Y,Z)=0在 A < X < B , A < Y < B , A < Z < B A< X < B, A < Y < B, A < Z < B A<X<B,A<Y<B,A<Z<B上的图形ezimplot3(f, [XMIN,XMAX,YMIN,YMAX,ZMIN,ZMAX])
画函数 f ( X , Y , Z ) = 0 f(X,Y,Z)= 0 f(X,Y,Z)=0 在 X M I N < X < X M A X , Y M I N < Y < Y M A X , Z M I N < Z < Z M A X XMIN< X < XMAX, YMIN < Y < YMAX, ZMIN < Z < ZMAX XMIN<X<XMAX,YMIN<Y<YMAX,ZMIN<Z<ZMAX上的图形
通过返回值来改变图像的属性的方法
实际上在函数文件"ezimplot3.m"的开头可以看到使用的语句是:function h = ezimplot3(varargin)
,是有返回值的,通过l=ezimplot3(@(x,y,z)x*y*z*log(1+x^2+y^2+z^2)-10,[-20,20])
可以得到l
变量的属性是patch
,是一种填充多边形,后面会介绍
可以通过点运算符访问成员来改变图像,可以help patch
来查询有哪些属性可以改变,一般会去改动的就是面颜色l.FaceColor
(默认为[1,0,0]
即红色)和面透明度l.FaceAlpha
(默认为0.7
)两项了
ezimplot3
函数的实现留坑,暂时学不会,涉及了很多函数和属性方面的知识
想法来源:链接
实际上只针对 v = f ( x , y , z ) v=f(x,y,z) v=f(x,y,z)类型的,其中 v v v的大小用颜色表示
直接上代码,估计用处不大
[x,y,z]=meshgrid(1:0.1:10,1:0.1:5,2:0.1:5);
v=x.^2+3*x.*y+4*y.*z;
xslice=[2,5,10];
yslice=2;
zslice=[2,4];
slice(x,y,z,v,xslice,yslice,zslice)
colormap hsv
关于“切片”部分的一个来源
这里的切面指的是 V = f ( x , y , z ) V=f(x,y,z) V=f(x,y,z)这种函数的切面,用来反应在某处的函数值
使用的函数是slide
,使用的时候直接help slide
即可
根据Matlab中文论坛的说法,Matlab并没有自带的截面函数
有一种暴力的方法,即使用ezimplot3
来实现截面的功能,不过个人觉得有点呆
思想来源和下一个一样,使用了位运算
例如,画 y = { c o s ( x ) x < = 0 a r c c o s ( x ) x > 0 y=\begin{cases}cos(x)&x<=0\\arccos(x)&x>0\end{cases} y={cos(x)arccos(x)x<=0x>0
直接上代码(范围可以自定,以 [ − π , 2 ] [-\pi,2] [−π,2]为例)
x=linspace(-pi,2);
y=(x<=0).*cos(x)+(x>0).*cosh(x);
plot(x,y),grid on,axis equal
当然使用fplot
和handle function
也是一样的
fplot(@(x)(x<=0).*cos(x)+(x>0).*cosh(x),[-pi,2]),grid on,axis equal
无论使用什么方法,都比之前介绍的分两段简单得多
思想来源:百度知道的链接,下面为答者使用的代码
[x,y]=meshgrid(-1:0.01:1); z1=2*x.^2+y.^2; mesh(x,y,z1) hold on z=1.*(x>=-1&x<=1); surf(x,y,z) hold off
这个脑洞确实很大,对于其他函数也可以使用类似的方法,见下
引用中的方法即这种方法的灵魂,利用位运算分割函数,确实是很厉害的想法
举个例子,如果要画 f ( x , y ) = { 1 2 ( x + y ) e − ( x + y ) x > 0 , y > 0 0 o t h e r s f(x,y)=\begin{cases}\frac{1}{2}(x+y)e^{-(x+y)}&x>0,y>0\\0&others\end{cases} f(x,y)={21(x+y)e−(x+y)0x>0,y>0others(函数来自概率论),直接使用下述代码即可
[x,y]=meshgrid(-1:0.1:4);
z=(x>=0&y>=0).*(1\2.*(x+y).*exp(-x-y));
surf(x,y,z)
包括Matlab的函数设计、与其他语言一起编程(走迷宫例子)
坑先放在这,这个是一个大坑,估计要很长时间以后才能填了