0%

MATLAB系列笔记

基本操作与矩阵操作

命令行

  1. 作用:输入操作命令,输出结果。
  2. 运算规则: 常见的四则运算规则(+ - * / ^)。
  3. help命令: 命令行输入。
1
help 需要查询的函数名
  1. ln代表指令:log

变量

  1. 可以在工作区观察每个变量的数值。
  2. 变量的开头不能是数字。
  3. who查看当前变量,whos查看当前变量具体性质。
  4. 特殊变量和常量:ij表复数,Inf无限大,eps无限小,pi表示圆周率 (pai)。
  5. 变量命名具有高优先级。
  6. 变量类型。(使用CTRL+点击可跳转)

数组(向量与矩阵)

  1. 行向量:[1 2 3 4],列向量:[1;2;3;4],矩阵:[1 21 6; 5 17 9; 31 2 7],这里的;可类似于换行符号。
  2. 数组索引:向量a(1) 矩阵A(1,2)orA(2)每一列按列数下去。
  3. Colon Operator:A=j:k(j到k逐次增加);A=j:i:k(j到k按i增加)。
  4. 矩阵合并的操作:使用A=[B C] B C行往后合并;A=[B;C]B和C列往后合并。
  5. 矩阵四则运算:同线性代数的四则运算。特殊的有
    • A/B相当于A × B的逆矩阵;
    • A.*B矩阵的各个元素相乘;
    • A./B矩阵的各个元素相除;
    • A+实数A的各个元素都相加这个实数,A/实数相当于A./实数,每个元素都除以这个实数;
    • A^2表示矩阵相乘,A.^2表示A的各个元素都平方;
    • A'表示A的转置。

结构化程序与自定义函数

MATLAB程序(.m文件)

  1. 注释代码:%,代码分部分:%%
  2. 以下为MATLAB基本编程语句:所有指令都以end为结束
    • 选择函数 if, elseif, else;switch, case;
    • 循环函数 for;while;
    • break跳出循环。
  3. 以下为MATLAB逻辑运算符:运算结果为trueorflase
    • 小于<;小于等于<=;大于>;大于等于>=;
    • 恒等于==;不等于~=;
    • &&;或||
  4. 以下为编程的一些技巧:
    • clear all清除所有变量;
    • close all关闭所有窗口;
    • clc清空命令行窗口;
    • ;命令行持续编写代码,但不执行;
    • 程序执行时,按下ctrl c,程序终止执行。

函数

函数书写规则

1
function output = FunctionName(v1,v2,v3...)

output为输出变量,FunctionName为函数名,()内的为函数变量

变量与档案储存

变量

数值

  1. 整型:int8, uint8(8代表数值所占比特数,u代表无符号数) int16, uint16, int32, uint32, int64, uint64
  2. 浮点数(可认为是小数):single(32位浮点值,也叫单精度变量),double(默认的变量类型,64位浮点值,也叫双精度分量)。
  3. 比如将一个数字转为double类型,则使用y=double(x),x是转换前,y是转换后。

逻辑

分为0(false)和1(true),为逻辑运算符(使用CTRL+点击可跳转)的输出结果。

字符

  1. 定义:s1='h'表示s1是一个字符,s2='hex'表示s2是一个字符串,是多个字符。
  2. 字符串合并:s1='example's2='string',合并:s3=[s1 s2],注意:s3=[s1;s2]s1s2并排放置,此时,s1s2的字符串长度要求一致
  3. 字符串索引:s1='string',那么s1(3)为r。str(100001(逻辑输出))=‘a’则,第一位和第六位变为a。
  4. 字符串比较:使用strcmp函数(CTRL+点击可跳转)

结构体

  1. 定义:结构体是一个存储{键: 值}的数据结构,使用.来访问结构体中的字段。类似于结构体里面为一个成员,成员有不同的属性值。

  2. 组成

    1
    struct(field1,value1,…,fieldN,valueN) % field为键,value为值

    field为属性名,value为属性值,属性值可以为任何变量类型。

  3. 创建结构体

    • 直接创建 :直接对结构体变量名.字段名赋值(字段的命名规则和变量一样)

      1
      2
      3
      4
      s(1).name = 'LiSi';
      s(1).gender = 'Male';
      s(2).name = 'LiSi';
      s(2).gender = 'female'; % 示例为创建了一个结构体对应两个变量
    • 使用struct()函数

      1
      s2 = struct('name', '李四', 'gender', 'male'); % filed1为name, value1为李四
  4. 不同成员的属性赋值:struct(n)struct为结构体名称,n为n个不同成员。

  5. 结构体常用函数

    image-20240404181739991

  6. 结构体的嵌套:结构体内部可以再包含结构体。课程中此处的结构体应该包含两个filed:data和nest,其中data为数字,nest为结构体。可以使用多个圆点去访问结构体中的结构体变量的值。

元胞数组

  1. 定义:元胞数组是一个可以容纳不同类型元素的数据结构,使用{}像定义矩阵一样定义元胞数组。

  2. 赋值

    • 单位索引赋值:A(m,n)={k},m和n表示为位于元胞数组m行n列位置,k为元素的值,k可为任何类型,矩阵也可。
    • 内容索引赋值:A{m,n}=k m,n,k的含义同上。
  3. 访问

    • 单位索引:A(1,1)得到A中的(1,1)位置的数据类型
    • 内容索引:A{1,1}得到A中的(1,1)位置的数据内容
  4. 常用函数

    • magic(n):产生nxn的[魔方矩阵](魔方矩阵_百度百科 (baidu.com))(CTRL+点击可跳转)

    • num2cell:将数组转换为相同大小的元胞数组,此时的元胞数组中元素为1x1的矩阵。

    • mat2cell:可以在转换的时候指定元胞数组各元胞的尺寸。

      1
      2
      mat2cell(a,[1 1 1],3) % a为需要操作的数组,[1 1 1]表示行怎么划分,3表示列怎么划分。这里表示化成三个1x3的子数组
      mat2cell(a,[2 1],[1 2]) % 表示把a矩阵(3x3)化成2x1,2x2,1x1,1x2的矩阵,然后组成元胞数组

      image-20240404214633785

高维数组

  1. 定义:将数组扩展到从一维(向量),二维(矩阵),三维(行row,列columm,层layer)

  2. 赋值

    • 使用{}定义三位元胞数组,如A{r,c,l}=valuer,c,l为对应行列层,value为对应位置的值,可以是任何类型。

    • 使用cat()函数在指定维度上对元胞数组进行拼接。

      1
      2
      3
      C=cat(1,A,B) %从行的维度对A和B进行拼接
      C=cat(2,A,B) %从列的维度对A和B进行拼接
      C=cat(3,A,B) %从层的维度对A和B进行拼接
  3. 常用函数

    reshape():改变数组的行列数

    1
    C=reshape(A,m,n) %A为lxk的数组,C为mxn的数组,其中mxn=lxk

文件读写

可以读取的文件类型有:MATLAB数据(.mat),Excel表格(.xls或者.xlsx)文件,空格分隔的数字(.txt)。

MATLAB数据

  1. 存储:save()函数
    • save(filename,variables)将变量variables以二进制形式存入文件中。
    • save(filename,variables,'-ascii')将变量variables以文本形式存入文件中。
  2. 读取:load()函数
    • load(filename)从二进制形式文件中读取数据。
    • load(filename,'-ascii')从文本形式文件中读取数据。
  3. 注意:这里的文件名要在文件和代码在同一目录下才能读取,若不在同一目录下,需要在此处改为文件路径。同时,这里的参数,filenamevariables都是字符串格式,若不指定variables参数,则将当前工作区内所有变量存入文件中。

Excel表格数据

  1. 读取:xlsread(),2019a开始后matlab不建议使用,以新函数代替。现在改用为:
    • readmatrix() 从文件中读取矩阵,格式:M=readmatrix('filename.xlsx','Sheet','sheetname','Range','rangenumber'),中Sheet,Range这两个是固定格式。或者直接M = readmatrixd('filename.xlsx') 读取文件中所有数据。
    • readcell() 从文件中读取元胞数组
    • readtable 基于文件创建表
  2. 存储:xlswrite(),2019a开始后matlab不建议使用,以新函数代替。现在改用为:
    • writematrix 将矩阵写入文件:可以writematrix(M, 'filename') 将矩阵 M 储存的数据写入表格 04Score.xls,也可以writematrix(M,'filename', 'Sheet', 1, 'Range', 'E2:E4') 规定范围写入指定表格,注意参数列表中 sheet后的参数可以是表格名也可以是第 x 个表格。
    • writematrix 将矩阵写入文件
    • writecell将元胞数组写入文件

文本数据

使用和写入excel相同的函数写入文本,就是指定的参数不一样,例如:writematrix写入文本。

  1. 直接 writematrix(M) 则默认以逗号分隔各元素写入 M.txt 文件中;
  2. 指定分隔符则使用writematrix(M, 'filename.txt', 'Delimiter', ' '); ‘Delimiter’是固定格式;
  3. matlab 支持使用 ``; \t,;|(对应的字符名称为
    space、tab、comma、semi、bar)作为分隔符。

低阶文件处理IO函数

使用fopen()函数打开文件或获得有关打开文件的信息。

  1. 无论是写入还是读取都要先获得fileID
    fileID = fopen(filename,permission) 将打开由 permission 指定访问类型的文件。permission 为文件访问类型:'r' (默认)读取 ,'w' 写入。
  2. 操作完毕后务必使用 fclose(fileID) 函数关闭文件,否则 matlab 将一直占用文件。
  3. 使用feof(fid) 检查是否到达文件结尾,到达结尾返回 true。

初阶绘图

基础绘图

plot()基本使用

  1. plot(x,y),x和y都是向量,要求长度一致。

  2. plot(y),此时x默认1,2,3,4...

  3. 设置曲线性质:plot(x,y,'linespec'),linespec可以设置线型、标记符号和颜色。

设置多条曲线性质:plot(x1,y1,'line1',x2,y2,'line2',...)

image-20240408212221452

  1. 需要保持多条图在一张图中(在一张图中显示多条曲线):hold on开始保持,hold off取消保持。

添加图例(在图右上角显示每条曲线代表意义)

1
2
plot('line1','line2','line3','line4');
legend('line1','line2','line3','line4'); % 这里的顺序和plot()中的对应顺序要一致

添加标题和坐标轴

  1. 添加标题:title('str');
  2. 添加坐标轴题注:xlabel()、ylabel()、zlabel()为 x y z 轴添加题注。

添加文本、线条和箭头

  1. 文本:text(x,y,str);
  2. 线条:line(x,y);
  3. 箭头:annotation(lineType, x, y) 创建一个在当前图窗中的两个点之间延伸的线条或箭头注释,将 lineType 指定为 line(线条)、arrow(箭头) 或 doublearrow(双向箭头),将 x 和 y 分别指定为 [x_begin, x_end] 和 [y_begin, y_end] 形式的二元素向量。

改变坐标轴的显示值

1
2
3
4
xticks([1 2 3 4])
xticklabels({'ET','et','lt','LT'}) %改变对应位置的值
yticks([0 1])
yticklabels({'0','1'})

更改图形属性

图形属性

画出的一个图主要包括 Figure Axes Line 三个 Object

获取图形句柄

图形句柄本质上就是一个浮点数,可以唯一确定一个图形对象.下面几个函数用于获取图形句柄.

函数 作用
gca() 获取当前坐标轴的句柄
gcf() 获取当前图像的句柄
allchild(handle_list) 获取该对象的所有子对象的句柄
ancestor(h,type) 获取对象最近的type类型的祖先节点
delete(h) 删除某对象
findall(handle_list) 获取该对象的后代对象

通过图形句柄改变图形属性

  1. 改变坐标轴属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    % 改变坐标轴字体大小
    set(gca, 'FontSize', 25);

    % 改变X轴坐标轴显示
    set(gca, 'XTick', 0:pi/2:2*pi);
    set(gca, 'XTickLabel', 0:90:360);

    % 把X轴显示改为自己想要显示的值
    set(gca, 'FontName', 'symbol');
    set(gca, 'XTickLabel', {'0', 'p/2', 'p', '3p/2', '2p'});
  2. 改变线型

    1
    2
    3
    4
    h = plot(x,y); 
    set(h, 'LineStyle','-.', ...
    'LineWidth', 7.0, ...
    'Color', 'g');

保存图片

使用saveas(fig,filename)命令可以将图形对象保存到文件中,其中fig为图形句柄,filname为文件名。

1
saveas(gcf, 'myfigure.png')

高阶绘图

进阶二维绘图

对数图

  1. logspace(-1,1,100):x取10^-1 到10^1中的100个变量。
  2. semilogx(x,y): x坐标轴是对数坐标系,即使用 x 轴以 10 为基数的对数刻度和 y 轴的线性刻度创建一个绘图。
  3. semilogy(x,y):y坐标轴是对数坐标系,即使用 y 轴以 10 为基数的对数刻度和 x 轴的线性刻度创建一个绘图。
  4. loglog(x, y):x、y坐标都是对数坐标系。
  5. set(gca,'XGrid','on'):加网格。

一图双Y轴

  1. 方法一:plotyy()以左、右不同纵轴绘制两条曲线。[AX,H1,H2] = plotyy( ):返回给AX两个坐标区(Axes)的句柄(handle),AX(1)表示左边的坐标区的handle,AX(2) 表示右边的坐标区的handle。返回给 H1H2 每个绘图中Line对象的handle.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    x = 0:0.01:20;
    y1 = 200*exp(-0.05*x).*sin(x);
    y2 = 0.8*exp(-0.5*x).*sin(10*x);
    [AX,H1,H2] = plotyy(x,y1,x,y2);
    set(get(AX(1),'Ylabel'),'String','LeftY-axis')
    set(get(AX(2),'Ylabel'),'String','RightY-axis')
    title('Labeling plotyy');
    set(H1,'LineStyle','--');
    set(H2,'LineStyle',':');
  2. 方法二:使用yyaxis()分别激活左右两个坐标轴,分别设置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    x = 0:0.01:20;
    y1 = 200*exp(-0.05*x).*sin(x);
    y2 = 0.8*exp(-0.5*x).*sin(10*x);

    yyaxis left;
    p1 = plot(x,y1);
    ylabel('LeftY-axis')
    title('Labeling plotyy');
    p1.LineStyle = '--';

    yyaxis right;
    p2 = plot(x,y2);
    ylabel('RightY-axis')
    p2.LineStyle = ':';

    清除左侧曲线命令:

    1
    2
    yyaxis left;
    cla;

直方图

  • hist(y)默认十个等间隔区间,并返回每个范围内的Y的元素个数作为一行向量。

  • hist(y,x)划分x个等间隔区间。这里的Y就是对应着纵坐标。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    x = [1 2 5 4 8];
    y = [x;1:5];
    subplot(1,3,1);
    bar(x);
    title('A bargraphof vector x');
    subplot(1,3,2);
    bar(y);
    title('A bargraphof vector y');
    subplot(1,3,3);
    bar3(y);
    title('A 3D bargraph');

条形图

  • bar()创建一个条形图。如果y是向量,y中每个向量对应一个条形,如果y是矩阵,则根据y中的行进行分组。

  • bar3()画3D图。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    x = [1 2 5 4 8];
    y = [x;1:5];
    subplot(1,3,1);
    bar(x);
    title('A bargraphof vector x');
    subplot(1,3,2);
    bar(y);
    title('A bargraphof vector y');
    subplot(1,3,3);
    bar3(y);
    title('A 3D bargraph');
  • bar(y,'stacked')为堆叠条形图,为了可以展示总和为多少。

  • barh(y)为水平条形图。

1
2
3
4
5
6
7
8
9
x = [1 2 5 4 8];
y = [x;1:5];
subplot(1,2,1);
bar(y,'stacked');
title('垂直堆叠图');

subplot(1,2,2);
barh(y,'stacked');
title('水平堆叠图');

饼状图

  • pie(a)使用a中的数据绘制饼状图,sum(a)≥0,则按比例绘制;sum(a)<1,则仅按比例绘制部分饼图。
  • pie(a,explode)将对应explode元素设置为1,使该部分偏移出去。
  • pie3()绘制3D饼图。
  • pie(x,{'Taxes','Expenses','Profit'})使用{}设置标签。
1
2
3
4
5
6
7
a = [10 5 20 30];
subplot(1,3,1);
pie(a);
subplot(1,3,2);
pie(a, [0,0,0,1]);
subplot(1,3,3);
pie3(a, [0,0,0,1]);

极坐标图

  • polar(theta,r)其中theta表示极角,r表示半径
  • 在最新版本中推荐使用:polarplot()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
x = 1:100;theta = x/10;
r = log10(x);
subplot(1,4,1);
polar(theta,r);
theta = linspace(0, 2*pi);
r = cos(4*theta);
subplot(1,4,2);
polar(theta, r);
theta = linspace(0, 2*pi, 6);
r = ones(1,length(theta));
subplot(1,4,3);
polar(theta,r);
theta = linspace(0, 2*pi);
r = 1-sin(theta);
subplot(1,4,4);
polar(theta , r);

箱线图与取样图

  • stairs()阶梯图:使用平行与x、y轴的线段连接各点。

  • stem()离散序列图:将各点与x轴垂直相连。

1
2
3
4
5
6
x = linspace(0, 4*pi, 40);
y = sin(x);
subplot(1,2,1);
stairs(y);
subplot(1,2,2);
stem(y);

填充图

  • 使用plot()是画线,而使用fill()是画线且涂色
  • fill(x,y,ColorSpec) 填充 x 和 y 指定的二维多边形(颜色由 ColorSpec 指定)
  • axis square off是``axis square(使当前区域为正方形)和axis off`(使数轴不可见)两个命令的组合命令
  • text()添加文本信息

配色

RGB

  • 在进行颜色设置时,matlab似乎不支持使用0255的数组来表示[R G B],将0255的数组每一项均除以255, 转换为0~1来表示即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
G = [46 38 29 24 13]; 
S = [29 27 17 26 8];
B = [29 23 19 32 7];
% 指定字符串标记x轴
str=categorical({'USA','CHN','GBR','RUS','KOR'});
% 画图的同时将各条形的handle赋给h,并将FaceColor属性设置为flat
h = bar(str, [G' S' B'],'FaceColor','flat');

for i=1:size(G',1) % 将每组第一个条形设置为金色
h(1).CData(i,:)=[1,0.843,0];
end
for i=1:size(G',1) % 将每组第二个条形设置为银色
h(2).CData(i,:)=[0.753 0.753 0.753];
end
for i=1:size(G',1) % 将每组第三个条形设置为铜色
h(3).CData(i,:)=[.545,.27,.0745];
end
title('Medal count for top 5 countries in 2012 Olympics');
ylabel('Number of medals'); xlabel('Country');
legend('Gold', 'Silver', 'Bronze') % 加上图例

将数据可视化为图像

  • meshgrid 函数用来生成网格矩阵
  • surf():画曲面图
  • box on 显示坐标轴轮廓
1
2
3
4
5
6
7
8
9
10
[x, y] = meshgrid(-3:.2:3,-3:.2:3);
z = x.^2 + x.*y + y.^2;
surf( x, y, z);
box on;
set(gca,'FontSize', 16);
zlabel('z');
xlim([-4 4]);
xlabel('x');
ylim([-4 4]);
ylabel('y');
  • imagesc(z) 将矩阵z中的元素数值按大小转化为不同颜色,并在坐标轴对应位置处以这种颜色染色;
  • 使用colorbar指令调出如图所示的颜色条;
  • 使用colormap()来改变可视化图像的颜色;

三维绘图

3D点或者线图

  • plot3(X,Y,Z) 在 3-D 空间中绘制坐标。

  • 要绘制一组由线段连接的坐标,请指定XYZ为相同长度的向量。

    要在同一组轴上绘制多组坐标,请至少将 XYZ,其中至少一个指定为矩阵,并将其他坐标指定为向量。

曲面图

  • [X,Y]=meshgrid(x,y):基于向量 x 和 y 中包含的坐标返回二维网格坐标。也就是说前面给出的x、y只是一个向量,而画网图需要x、y两个范围围出来的面上的所有点,meshgrid(x,y)则给出这个面上所有的点。
  • surf(X,Y,Z) 创建三维曲面图,该图面是具有纯边色和实心脸色的三维曲面。该函数将矩阵中的值绘制为由 和 定义的 x-y 平面中网格上方的高度。表面的颜色根据 指定的高度而变化。(绘制网格并填充颜色)
  • meshsurf的区别:surf会把颜色贴在上面。

矩阵等值线图

  • contour:等高线/轮廓
  • 在contour后面加数值可以让contour画线更加紧密;例如contour(Z,[-.45:.05:.45]);
  • 我们还可以在图上把数值标上去,用clabel指令:clabel(C,h);
  • 也可以给contour涂颜色,contourf(),f是fill的意思。

网格曲面图下及曲面图下的等高线图

视点控制以及打光设置

  • view(Az,El)其中Az为方位角,El为高度角;也可以输入三个参数,view(x,y,z),其中(x,y,z)是直角坐标系中一个矢量。

    1
    2
    3
    4
    5
    6
    7
    8
    sphere(50);
    shading flat;
    light('Position',[1 3 2]);%添加灯光,让球更立体
    light('Position',[-3 -1 3]);
    material shiny;
    axis vis3d off;%不显示三维坐标系
    set(gcf,'Color',[1 1 1]);
    view(-45,20);%这个可以决定角度
  • 可以旋转查看球体:使用图形界面的三维旋转选项,这时左下角会出现观察的球坐标角度表示。

  • 定义light的打光位置和颜色:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [X, Y, Z] = sphere(64);
    h = surf(X, Y, Z);
    axis square vis3d off;
    reds = zeros(256, 3);
    reds(:, 1) = (0:256.-1)/255;
    colormap(reds);
    shading interp;
    lighting phong;
    set(h, 'AmbientStrength', 0.75, 'DiffuseStrength', 0.5);
    L1 = light('Position', [-1, -1, -1]);

绘制多边形

  • patch()绘制一个或多个填充多边形区域

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    v = [0 0 0; 1 0 0 ; 1 1 0; 0 1 0; 0.25 0.25 1; 0.75 0.25 1; 0.75 0.75 1; 0.25 0.75 1];
    f = [1 2 3 4; 5 6 7 8; 1 2 6 5; 2 3 7 6; 3 4 8 7; 4 1 5 8];
    subplot(1,2,1);
    patch('Vertices', v, 'Faces', f, 'FaceVertexCData',hsv(6),'FaceColor','flat');
    view(3);
    axis square tight;
    grid on;
    subplot(1,2,2);
    patch('Vertices', v, 'Faces', f, 'FaceVertexCData',hsv(8),'FaceColor','interp');
    view(3);
    axis square tight;
    grid on;