Matlab静态曲线和动态曲线绘制在同一个图上(针对二维平面)
重新发布一下,(优快云,未经允许,把我写的东西自动转化成VIP文章,重新在发一下应该是免费了)
一.静态画图说明
用到的matlab版本:2019a
matlab画图经常用到figure和plot函数,这两个函数往往配合在一起进行使用。根据官方文档可以知道,figure的作用是创建当前图窗,也就是说当你使用figure函数时,此后的图都会在这个图窗中显示。当一个程序中出现多个figure函数时(前提图窗名字各不相同),接下来的图像会在最近调用的figure图窗内显示。
来看一个例子:
//创建一个名叫测试1的图窗,其余参数可查看官方文档
figure('name','图窗1', 'numbertitle', 'off');
//图画标题
title('静态图多图显示1');
xlabel('x');%横轴名称
ylabel('y');%纵轴名称
x1 = 0:0.1:10;
y1= sin(x1);
x2 = 0:0.2:20;
y2 = cos(x2);
//hold on语句使得图像叠加,不加此句plot只会画最后一次调用时画的曲线,即会覆盖原来的曲线
//但是作用域仅仅局限于该图窗内,在下一图窗如果还想要进行多图显示还得在加上hold on;
hold on;
//画图,plot具有多个参数,可查看官方文档去结合自己实际使用
plot(x1,y1,'r');
plot(x2,y2,'g');
//图例,一般一个图有多个曲线时会用到
legend('sin','cos');
figure('name','图窗2', 'numbertitle', 'off');
hold on;
title('静态图多图显示2');%图画标题
xlabel('x');%横轴名称
ylabel('y');%纵轴名称
x3=0:0.2:6;
y3=2*x3;
y4=5+0*x3;%常数的话,不加0*x3无法显示直线
plot(x3,y3);
plot(x3,y4);
//legend要放在plot之后,放在之前会有警告,具体见官方文档
legend('y=2x','y=5');
结果如下:
各个函数对应的显示内容在图中有注释标出
图窗2同理
二.多张动图按顺序先后显示在一张图上
先后显示的逻辑就是在一个窗口内,按顺序显示要展示的动态曲线,比如有三条曲线,按照之前文章所写按顺序添加要展示的图片就可以,个人认为这个不常用。
回顾一下如何画单个动态图吧,代码如下:
x = 0:0.1:2*pi;%x的取值范围,步长为0.1
y = cos(x);%y与x之间的关系
axis([0 8 -5 5]);%限制XY轴的范围,这个根据图像自己设定。
line = animatedline('Color','r','LineWidth',3);%创建一个动态线条,参数可更改,根据自己情况看文档修改
for i=1:length(x)
addpoints(line,x(i),y(i));%向指定的动画线条中添加 x 和 y 定义的点
MakeGif('GifTest1.Gif',i);%保存动态图,这个是自定义函数,
%需要包含在与main文件同一个文件夹下,这个参数第一个是
%图片名称,注意必须是xxx.GIf格式,否则报错。xxx随便起中文英文均可,第二个参数是图片个数,图片个数与离散坐标点有关
%最后生成的gif图片会在你当前运行的程序文件中的路径。
pause(0.1);%调节此参数可以调节曲线动态显示速度drawnow;%更新图形,新点会自动连接到之前的点
end
直接看结果
好,想要在一张图上显示多条曲线,直接叠加就可以。比如显示3个图像,那我直接来3个for循环即可(当然本着程序能用的原则,不考虑诸如代码冗余性高、运行时间等因素),接下来就是体力活,具体代码如下:
clc;%清空命令行窗口
close all;%关闭所有图形窗口
clear;%清空所有变量区
figure('name','多条动态曲线绘制在同一个图上', 'numbertitle', 'off');
x = 0:0.1:2*pi;%x的取值范围,步长为0.1
x1 = 0:0.2:3*pi;
x2 = 0:0.1:8;
y = cos(x);%y与x之间的关系
y1 = sin(x1);
y2 = 0.5*x2;
axis([0 8 -5 5]);%限制XY轴的范围
line = animatedline('Color','r','LineWidth',3);%主要是animatedline(动态线条)的应用
line1 = animatedline('Color','y','LineWidth',3);
line2 = animatedline('Color','b','LineWidth',3);
for i=1:length(x)
addpoints(line,x(i),y(i));%向 an 指定的动画线条中添加 x 和 y 定义的点
MakeGif('GifTest1.Gif',i);%保存动态图
pause(0.1);%调节此参数可以调节曲线动态显示速度
drawnow;%更新图形,新点会自动连接到之前的点
end
for i=1:length(x1)
addpoints(line1,x1(i),y1(i));%向 an 指定的动画线条中添加 x 和 y 定义的点
MakeGif('GifTest2.Gif',i);%保存动态图
pause(0.1);%调节此参数可以调节曲线动态显示速度
drawnow;%更新图形,新点会自动连接到之前的点
end
for i=1:length(x2)
addpoints(line2,x2(i),y2(i));%向 an 指定的动画线条中添加 x 和 y 定义的点
MakeGif('GifTest3.Gif',i);%保存动态图
pause(0.1);%调节此参数可以调节曲线动态显示速度
drawnow;%更新图形,新点会自动连接到之前的点
end
这个代码可以运行出来但有一个问题,在该程序下gif图不能保存所有线条的动态过程,以最后生成的GifTest3.Gif动图为例。效果如下:
这样肯定不行,在魔改一下。变成下面这个格式,这样整个过程的动图就可以保留了
clc;%清空命令行窗口
close all;%关闭所有图形窗口
clear;%清空所有变量区
figure('name','多条动态曲线绘制在同一个图上', 'numbertitle', 'off');
title('动态图不同步显示在一个图上');
xlabel('x');
ylabel('y');
x = 0:0.1:2*pi;%x的取值范围,步长为0.1
x1 = 0:0.2:3*pi;
x2 = 0:0.1:8;
y = cos(x);%y与x之间的关系
y1 = sin(x1);
y2 = 0.5*x2;
axis([0 8 -5 5]);%限制XY轴的范围
line = animatedline('Color','r','LineWidth',3);%主要是animatedline(动态线条)的应用
line1 = animatedline('Color','y','LineWidth',3);
line2 = animatedline('Color','b','LineWidth',3);
legend('y','y1','y2');%加上图例
for i=1:length(x)+length(x1)+length(x2)
if(i<=length(x))
addpoints(line,x(i),y(i));%向 an 指定的动画线条中添加 x 和 y 定义的点
pause(0.1);%调节此参数可以调节曲线动态显示速度
drawnow;%更新图形,新点会自动连接到之前的点
end
if(i>length(x)&&i<=length(x)+length(x1))
addpoints(line1,x1(i-length(x)),y1(i-length(x)));%向 an 指定的动画线条中添加 x 和 y 定义的点
pause(0.1);%调节此参数可以调节曲线动态显示速度
drawnow;%更新图形,新点会自动连接到之前的点
end
if(i>length(x)+length(x1)&&i<=length(x)+length(x1)+length(x2))
addpoints(line2,x2(i-length(x)-length(x1)),y2(i-length(x)-length(x1)));%向 an 指定的动画线条中添加 x 和 y 定义的点
pause(0.1);%调节此参数可以调节曲线动态显示速度
drawnow;%更新图形,新点会自动连接到之前的点
end
MakeGif('MyGif.Gif',i);%保存动态图
end
如下图所示:
改进的思路就是将三个for循环变成一个for循环,根据进入条件不同依次执行要显示的曲线,只不过保存图片的函数贯穿整个for循环,对于自定义函数MakeGif中的第二个参数,我理解的是图片个数,因为动图是多个图片叠加而成,MakeGif函数就是将保存的所有图片都显示在一个图窗中这样就成了动图,因此对于函数,你有多少个离散点就有多少张动图,想要全过程保存就是要得到全过程的图片数。对于先后显示的动态图,全过程图片数就是上述例程中三条曲线对应的图片数之和。而图片数之和等于三条曲线对应的离散点数之和。
三.多张动图同时显示在一张图上
多张动图同时显示,个人认为是常用的,直接上代码:
figure('name','多条动态曲线同步绘制在同一个图上', 'numbertitle', 'off');
axis([0 10 -5 5]);%限制XY轴的范围
title('多条曲线同步显示');
x = 0:0.1:2*pi;%x的取值范围,步长为0.1
x1 = 0:0.1:3*pi;
x2 = 0:0.1:8;
y = cos(x);%y与x之间的关
y1 = sin(x1);
y2= 0.5*x2;
xlabel('x');
ylabel('y');
line = animatedline('Color','r','LineWidth',3);%主要是animatedline(动态线条)的应用
line1 = animatedline('Color','y','LineWidth',3);
line2 = animatedline('Color','g','LineWidth',3);
legend('y','y1','y2');
for i=1: length(x1)%选择离散点最大的那个
if(i<=length(x))%不符合进入条件说明该曲线点以画完
addpoints(line,x(i),y(i));%向 an 指定的动画线条中添加 x 和 y 定义的点
end
if(i<=length(x1))
addpoints(line1,x1(i),y1(i));
MakeGif('Test.Gif',i);%保存整个动态图像
end
if(i<=length(x2))
addpoints(line2,x2(i),y2(i));
end
pause(0.1);%调节此参数可以调节曲线动态显示速度
drawnow;%更新图形,新点会自动连接到之前的点
end
结果如下:
,之后通过if循环判断各个曲线是否绘制完毕。以上述代码为例,三条曲线中,x1离散点是最多的,把它设置为最大条件即可,保存动图的函数一定要放在离散点最多的那条曲线对应的if循环中。因为,同步显示时,决定动图长短的是你最大离散点的个数。
四.一些感想
(1).关于步长和最大值对曲线刷新速度的影响
关于离散点个数:
比如对于x2=0:0.1:8,一共有81个点,这81个点构成动态曲线
以三章节中多张动图显示在一个图上的代码为例。原始条件为:
x = 0:0.1:2*pi;%x的取值范围,步长为0.1
x1 = 0:0.1:3*pi;
x2 = 0:0.1:8;
y = cos(x);
y1 = sin(x1);
y2= 0.5*x2;
由于步长一样,最大值不一样,导致离散点个数不同,进而最终曲线不能够同时结束刷新。更改条件,把最大值全部设置为10。
x = 0:0.1:10;%x的取值范围,步长为0.1
x1 = 0:0.1:10;
x2 = 0:0.1:10;
y = cos(x);
y1 = sin(x1);
y2= 0.5*x2;
三条曲线同步开始同步结束,结果如下:
(2).
最大值一样,步长不一样,最终离散点个数也不一样。这体现在曲线刷新速率不同,初始条件如下:
x = 0:0.3:10;%x的取值范围,步长为0.1
x1 = 0:0.1:10;
x2 = 0:0.2:10;
y = cos(x);
y1 = sin(x1);
y2= 0.5*x2;
步长越小,刷新越慢,结果如下:
(3).步长和最大值都不一样,但离散点个数一样。最终呈现的是曲线刷新速率不同,但所有曲线都会同时结束刷新。条件如下:
x = 0:0.2:10;%x的取值范围,步长为0.1 51个离散点
x1 = 0:0.1:5;%51个离散点
x2 = 0:0.2:10;%51个离散点
y = cos(x);
y1 = sin(x1);
y2= 0.5*x2;
y1,y2离散点个数是一样的最终会同时停止刷新。但它们刷新速率是不同的。
因此在以后作图的时候,最好让步长一致,这样曲线是同步速率进行刷新的,这样方便观察。
(当然实验可能不太严谨)
补充:
matlab提供了强大的函数库,通过学习官方文档以及官方例子来学会一些函数对我们来说是必要的。以figure函数为例子:
首先光标在figure上右键选中关于figure的帮助(或者按F1)
之后会弹开窗口,点击打开帮助浏览器即可
查看对应资料即可
最后对应实验代码链接: https://download.youkuaiyun.com/download/m0_52209687/88758495
以上就是所有内容。根据自己的要求更改就行。
希望自己坚持记录!