引言
本人是一位数学科研工作者,平时的文章采用的是latex编写,里面图形的生成主要来自于Matlab(个人对Matlab非常喜欢,感觉上手比较容易,更亲民)。对于图形的处理比较频繁,而且总会有一些特殊的需求,每次都要上网搜查,或者查以前用过的命令,经常花了很多时间,实现了一点小要求,事后回想有点得不偿失。因此借助这个平台,记录自己在Matlab使用过程中碰到的一些问题,给出我找到或者知道的解决办法,不过方法不是唯一的,也希望广大网友能有更好的思路提供。后续碰到的问题我也会继续更新(如果我有时间的话哈)。
Matlab画三维图
Matlab画三维图形的需求通常是针对二元函数而言的,Matlab画图主要采用描点的方法,就是画出给定点对应的值,然后Matlab会自动把这些点连接起来,就成了很漂亮的一幅图。所以你给的点越多,画的图就越精确。
一个简单的例子
下面我们以函数 u = s i n x ) s i n y ) u=sinx)siny) u=sinx)siny)为例,画三维图形的代码如下:
function PF_3D
px=100; py=150; %x轴我布100个点,y方向布150个点
x=linspace0,2*pi,px); %该函数表示在[0,2*pi]上均匀布px个点
y=linspace0,2*pi,py);
[X,Y]=meshgridx,y); %该函数的作用详见下文
u=sinX).*sinY); %计算对应点的函数值u %注意点乘
surfX,Y,u); %画图
%meshX,Y,u);
end
代码中的meshgrid命令是生成 m × n m\times n m×n的X,Y两个矩阵,这里m是y的长度,n是x的长度,结果如下图Matlab代码
X就是把x向量复制了m行,每行都一样。Y就是把y复制了n列,每列都一样,这样X,Y矩阵相同位置的值就对应了点的横纵坐标(总共有 m × n m\times n m×n个点),再由前面代码计算得到u就得到点对应的函数值。最后可以通过mesh或者surf命令进行画图就。mesh和surf是有区别的,但是我也没去区分,我自己常用的是surf命令,下面看两个命令画出图的不同左边是surf,右边是mesh)
上图中左边surf画出来的图比较黑那是因为Matlab在图上画了黑色网格线,如果要去掉他可以在后面加命令:
shading interp
效果如图:
如果不喜欢后面坐标平面的那些网格线,也可以加命令:
grid off
就可以让它消失。
坐标轴的设置
1.从上面的图可以看出,如果不加干预的话,Matlab画出你给的横纵数值范围的全部图形,但有些时候我们可能比较关心局部的图样,这时候就要设置图形坐标轴的显示范围,只要在surf命令后面加命令:
axis[0,2,0,4,0,1])
axis里面参数分别对应x_min,x_max,y_min,y_max,z_min,z_max,效果如图
2.有些问题他的图形是长条形的,如x轴应该很长,y,z轴比较短的,但Matlab总是画得“方方正正”,这样就会变得不美观(肯定有个轴被压缩),所以此时我们选择控制轴的相对长度,可以在surf后面加命令:
pbaspect[2,1,1]);
pbaspect后面得三个参数表示横纵竖得长度比例是2:1:1,最后效果如图:(我们这个例子不需要让轴变长,拉长反而不好看,为了演示拼了)
3.隐藏坐标轴。有时候我们保存多张图,只是为了体现图形的变化,这样就不需要每个坐标轴刻度和数值都显示出来,所以我们要隐藏坐标轴,这个在网上有很多人提供了方案,但是个人觉得比较好用的方案是在surf后面添加如下命令
t=0:0:0;
setgca,'xtick',t); %这两句话可以去掉x轴的刻度和坐标值
xlabel'x轴的说明') %这句话可以坐标的下面添加一个说明
setgca,'ytick',t); %这两句话可以去掉y轴的刻度和坐标值
ylabel'y轴的说明') %这句话可以坐标的下面添加一个说明
setgca,'ztick',t); %这两句话可以去掉y轴的刻度和坐标值
zlabel'z轴的说明') %这句话可以坐标的下面添加一个说明
直接看效果
横纵竖的刻度和刻度值都消失了,留下了三条边缘黑线,至于这个怎么去了目前还不知道(是不是可以设置刻度线的颜色成白色就行?)。上面的方案原出处可以在该网页查看。
4.其他坐标轴设置。还有很多坐标轴的设置可以直接上网查找,或者直接编辑图片,如何编辑呢?就是直接在生成的图像窗口点查看-属性编辑器(我用的2019版本的是这样,在以前的版本在图形窗口有个图标直接点就行了,但是19版本没有了,感觉没有了很难受,谁知道怎么添加这个属性编辑器的快捷图标到工具栏里)。进入属性编辑器之后,就会发现里面有好多对图形的坐标轴的设置,还是挺好用的,但是如果对很多图同时处理的画,这样效率很低,还是能用代码解决的就用代码解决。
图形的视角
有时候我们不需要三维的立体图,可能只要俯视图或者侧视图,通过图形的颜色区别函数值的大小。这时候我们就需要对图形进行旋转,一种办法就是直接对生成图形进行旋转看工具栏上有,或者鼠标移到图上就有这个旋转工具跳出来)。第二种办法就是加命令
view0,90) %俯视图xoy平面,x为横轴
%view-90,0) %侧视图yoz平面,y为横轴
%view0,0) %侧视图xoz平面,x为横轴
效果如图
但这样光有颜色没有标明颜色对应的值,我们可以在图形窗口点插入颜色栏图标(上图工具栏中的第六个图标)会在右侧出现颜色栏。如果对这个颜色栏不喜欢,可以右击刚生成的颜色栏选择标准颜色图,选自己喜欢的打勾就行(我比较喜欢jet)。上面的过程也可以直接采用如下命令实现:
colorbar %显示颜色栏
colormapjet) %颜色的风格选择
图像的保存
图像的保存一种就是直接在图形窗口,文件-另存为就有好多的格式供你选择,我们写论文的时候一般要求是eps格式的图片,因为它是矢量图,放大不失真,Matlab有提供这个选择,两个字完美!这种通过选择保存图片的方式非常笨拙,一两个图还行,多个图的产生,或者程序需要长时间运行的不想干等的就比较麻烦,所以还是代码来解决吧。
我们以一个例子来爽快的解决这个问题。比如我们打算画函数图
u = s i n k x ) c o s k y ) u=sinkx)cosky) u=sinkx)cosky)这里的 k k k的取值[1,2,3],现在要将每个 k k k对应的图保存到当前路径的figures文件夹里(这个文件夹要原先要存在),文件命保存成fg1.fig,fg2.fig,fg3.fig(.fig是Matlab图形保存是默认的后缀名,这样后缀的图形可以再由Matlab打开)。给出如下代码:
function PFS
px=100; py=150; %x轴我布100个点,y方向布150个点
x=linspace0,2*pi,px); %该函数表示在[0,2*pi]上均匀布px个点
y=linspace0,2*pi,py);
[X,Y]=meshgridx,y); %该函数的作用详见下文
fid=[pwd,'\figures\']; %这个命令用fid指当前路径下的figures文件夹
for k=1:3
u=sink*X).*sink*Y); %计算对应点的函数值u %注意点乘
figurek) %创建第k个图形窗口
surfX,Y,u); %画图
M=int2strk);%将k转化成字符存到M中
saveasgcf,[fid,'f',M,'.fig']);
end
end
上段代码的核心:1.创建图窗 2.保存图形。先看创建图窗的命令就是
figurek) %创建第k个图形窗口
注意k一定要加括号,没有括号不行。这个figure命令是k的for循环命令内,这样就可以随着k的变化创建不同的图窗,然后再fiugurek)后面跟上画图命令,图就会画到相应的图窗。这样就避免了后面画的图覆盖前面画的图情形。接着就是保存图形,我们首先再for循环的外围给命令
fid=[pwd,'\figures\'];
这个fid变量是为了保存图像要保存的路径,参数pwd是Matlab自带的表示当前路径,\figures\就是figures文件夹(因为所有的图都要保存到这个文件夹里,所以这个命令放在for循环的外面)。在for循环内容我们要给图像名字起fg1.fig,fg2.fig,fg3.fig,注意名字上的1,2,3其实就是k的值,但是k是个数值(整数值),而文件名应该是个字符串,所以首先先将k转化成字符串
M=int2strk);%将k转化成字符存到M中
然后再合成一个完整的路径就是[fid,‘f’,M,’.fig’],这个中括号,中间逗号起到了字符串左右拼接的作用,注意里面已经是字符串了不用加引号,不是的要加。最后通过saveas函数进行图像保存:
saveasgcf,[fid,'f',M,'.fig']);
saveas第一个参数gcf我也不知什么意思,是否是获取图片的意思,我就当默认处理了。
如果是要将图片保存成eps格式的画,要把saveas的参数命令中的’.fig’改成’.eps’,但如果仅仅如此的话,保存最终的eps图像是黑白的(我的Matlab是这样,不知道你们是否也是),如果想要是彩色的,要在后面额外加一个参数’psc2’,具体代码如下:
saveasgcf,[fid,'f',M,'.eps'],'psc2');
这样就大功告成。
结束语
如果读者有碰到一些Matlab的问题也可以留言提问,如果我知道的话也会告知。
文中很多方法是我看书或者搜索到的,如果有侵权请告知,我深表歉意。