Matlab绘制动态 .gif 图
2017-08-20 本文已影响0人
木子识时务
有的时候,gif 有助于对问题的理解,下面就介绍一下如何利用Matlab来绘制gif图。主要是源代码及结果展示,代码里面有注释,根据自己的需求,进行修改即可。
注:
- 以下程序均需另存为 m 文件运行,运行后在Matlab的当前路径下,可以看到相应的 gif 文件。
- 有的 gif 图片是由多个 gif 图片拼接而成的,拼接时所用的软件是 ulead gif animator, 可自行搜索下载。
- 所测试的 Matlab版本是 R2016b,太低的版本可能没法运行
参考内容:
MATLAB getframe用法
matlab制作GIF之hello world
1. 表现绘图过程,即图形的增长过程
%适用于在一幅图中表现给图过程,即图形的增长过程
%主要用来绘制三维的欧拉公式
clc;clear;clf;close all;
%获得数据
tmax = 4*pi;
t = 0:0.01:tmax;
tmp = exp(1i*t);
x = real(tmp);
y = imag(tmp);
[a,b] = size(x);
y1 = zeros(a,b) ;
x1 = zeros(a,b);
%确定首幅图的样式,并指定标题,坐标轴标题等样式
plot3(x(1,1),t(1,1),y(1,1),'black');
hold on
plot3(x(1,1),t(1,1),y1(1,1),'blue');
plot3(x1(1,1),t(1,1),y(1,1),'r');
axis([-1,1,0,tmax,-1,1])
str = ['$${e^{it}} = \cos t + i\sin t $$',char(13,10)','created by Lijunjie!'];
title({str},'interpreter','latex')
xlabel('实轴');
ylabel('时间轴');
zlabel('虚轴');
grid on;
set(gcf,'Position',[0,0,600,600], 'color','w');
set(gca,'ydir','reverse') %反转坐标轴
%确保图像在采集的过程中包括坐标轴及标题
ax = gca;
ax.Units = 'pixels';
pos = ax.Position;
ti = ax.TightInset;
rect = [-ti(1), -ti(2), pos(3)+ti(1)+ti(3), pos(4)+ti(2)+ti(4)];
%在指定的范围内获得图像文件
frame = getframe(ax,rect);
im=frame2im(frame);
%创建gif文件,指定其样式,写入首帧图像
k = 1;
%用胞元存储采集到的图像,方便后面反转图像用
[I{k},map{k}]=rgb2ind(im,256);
imwrite(I{k},map{k,1},'mygif.gif','gif','Loopcount',Inf,'DelayTime',0.2);
k = k + 1;
%画图并采集到gif中
steptmp = 20; %每幅图要画的点数
i = steptmp;
while i < (b-1)
x_1 = x(1,(i-steptmp+1):i+1);
t_1 = t(1,(i-steptmp+1):i+1);
y_1 = y(1,(i-steptmp+1):i+1);
y1_1 = y1(1,(i-steptmp+1):i+1);
x1_1 = x1(1,(i-steptmp+1):i+1);
plot3(x_1,t_1,y_1,'black');
hold on
plot3(x_1,t_1,y1_1,'blue');
plot3(x1_1,t_1,y_1,'r');
%下面是制作gif的主要代码,除了调节间隔时间外,一般不需要改动
ax = gca;
ax.Units = 'pixels';
pos = ax.Position;
ti = ax.TightInset;
rect = [-ti(1), -ti(2), pos(3)+ti(1)+ti(3), pos(4)+ti(2)+ti(4)];
frame = getframe(ax,rect);
im=frame2im(frame);
[I{k},map{k}]=rgb2ind(im,256);
%写入模式为“追加”模式
imwrite(I{k},map{k},'mygif.gif','gif','WriteMode','append','DelayTime',0.1);
k = k + 1;
i = i + steptmp;
end
%将图像按相反的顺序再写入到gif中
for i = (k-1):-1:1
imwrite(I{i},map{i},'mygif.gif','gif','WriteMode','append','DelayTime',0.1);
end
结果图:
图1
2. 表示一个参数对图形的影响
代码如下:
function second_order_system_gif_1()
%此种情况用来表示某个参数变化时,对相关图形的影响
%此函数用来表示当二阶系统的共轭极点的虚部变化时对系统的
%频率响应和阶跃响应的影响
%后期可以通过Ulead GIF Animator软件将这4张gif合并在一起
%问题:图像大小设置为某些值时,可能会出错,需要重新调整
clc;clear;close all;
%初始化数据
b = 2;
a = 0:0.5:20;
[~,size_a] = size(a);
num = b.^2 + a.^2;
for i = 1:size_a
den{i} = conv([1 b + a(i) * 1i],[1 b - a(i) * 1i]);
end
w = 0:0.01:30;
k = 1;
%有多幅图,用胞元数组来指定文件名,从而方便在循环中使用
fieldnames = {'1.gif','2.gif','3.gif','4.gif'};
%画图,并制作gif
%由于每次画图都要擦掉上一次画的图,所以图形不能一直用hold on
for i = 1:1:size_a
%完成图像的绘制,为了保证效果,要保证图像大小以及
%坐标轴的范围不变
figure(1);
set(gcf,'Position',[0,0,300,400], 'color','w');
[hz,hp,ht] = zplane(num(i),den{i});
hold on;
x_data = [0 hp.XData 0];
y_data = [0 hp.YData 0];
plot(x_data,y_data,'--');
ylim([-22,22]);
xlim([-6,6]);
title(['二阶系统的极点',char(10,13)',...
'Created by Lijunjie']);
set(gca,'XTick',[-6:2:6]);
hold off
%采集绘制频率响应的数据
h = freqs(num(i), den{i},w);
mag = abs(h);
phase = angle(h);
phasedeg = phase*180/pi;
figure(2)
picture_positon;
plot(w,mag);
grid on;
xlabel 'Frequency (rad/s)', ylabel Magnitude
ylim([0 5.5]);
xlim([0 30]);
title(['二阶系统的幅频特性',char(10,13)',...
'Created by Lijunjie']);
figure(3);
picture_positon;
plot(w,phasedeg);
xlabel 'Frequency (rad/s)', ylabel 'Phase (degrees)';
ylim([-200,0]);
xlim([0 30]);
title(['二阶系统的相频特性',char(10,13)',...
'Created by Lijunjie']);
sys = tf(num(i),den{i});
figure(4)
[y_tmp,t_tmp] = step(sys,3.5);
plot(t_tmp,y_tmp);
picture_positon;
title(['二阶系统的阶跃响应',char(10,13)',...
'Created by Lijunjie']);
xlabel('Time(seconds)');
ylabel('Amplitude');
axis([0 3.5 0 2]);
%制作pdf
if i == 1
%采集到首帧,需要设置gif的样式,以及确定图像的大小
for j = 1:4
figure(j)
frame = getframe(gcf); % 获取整个窗口内容的图像
im=frame2im(frame);
[I{j,k},map{j,k}]=rgb2ind(im,256);
imwrite(I{j,k},map{j,k},fieldnames{j},'gif','Loopcount',Inf,'DelayTime',0.2);
end
else
for j = 1:4
figure(j)
frame = getframe(gcf);% 获取整个窗口内容的图像
im=frame2im(frame);
[I{j,k},map{j,k}]=rgb2ind(im,256);
%追加模式
imwrite(I{j,k},map{j,k},fieldnames{j},'gif','WriteMode','append','DelayTime',0.1);
end
end
k = k + 1;
end
%将采集到的图像以相反的顺序写入
for i = (k-1):-1:1
for j = 1:4
imwrite(I{j,i},map{j,i},fieldnames{j},'gif','WriteMode','append','DelayTime',0.1);
end
end
function picture_positon
%设置图像的大小
set(gcf,'Position',[0,0,600,400], 'color','w');
end
end
结果是四幅图,如下:
图2
图3
图4
图5
用ulead gif animator合并后的效果如下:
图6