2017-01-19 20 views
0

Я хочу создать анимированный gif решения уравнения с частными производными. То есть gif должен показать решение в определенное время.Как создать анимированный GIF в MATLAB?

example

В настоящее время я могу только сделать снимки, в которых изображены все времена. Ниже представлена ​​моя вся программа, с figure(3) моей попыткой сделать gif.

clear all; 
close all; 
%%%%%%%%%%%% 
% For slide 27 of Diffusion 1D 
% The equation to be graphed in latex form is 
% u(x,t)=\frac{1}{L}+\frac{2}{L}\sum^{\infty}_{n=1}cos(\frac{n\pi x_0}{L})cos(\frac{n\pi x}{L})e^{-k(\frac{n\pi}{L})^2t} 
%%%%%%%%%%%% 

%define constants 
%note that the constants listed in the file are arbitrary 
L = 2; %length of the rod 
k= 0.01; % Diffusivity, which is assume to be constant but can be a function of x 
x0 = 1; %location of the inital condition i.e. f(x)=delta(x-x0) 
tmax= 50; %maximum amount of time the simulation runs 
nmax = 200; % maximum value for n, increase to accuracy 
tgrid = 21; %The number of points to be evaluated in the time domain 
xgrid = 51; %The number of points to be evaluated in the space domain 

%initialize variables 
u=zeros(tgrid,xgrid); %preallocate array used for storing values of the solution 
t=linspace(0,tmax,tgrid);%We assume that time is evenly distributed 
x=linspace(0,L,xgrid); %We assume that space is evenly distributed 

%Plotting variables 
figure(1); 
hold on; 
axis([0 L -inf inf]); 
xlabel('x'); 
ylabel('u(x,t)'); 
%Calculation, 
for i=1:tgrid 
    for j=1:xgrid 
     seriesSum=0; 
     %Calculate the fourier series up to nmax for each point u(x,t) 
     for n= 1:nmax 
      seriesSum= seriesSum + cos(n*pi*x0/L)*cos(n*pi*x(j)/L)*exp(-k*t(i)*(n*pi/L)^2); 
     end 
     %Finish calcuation for solution at a specific point 
     u(i,j)= 1/L+(2/L)*seriesSum; 
    end 
    %After we have calculated all points at time t, we graph it for time t 
    plot(x,u(i,:),'linewidth',4); 
end 
saveas(gcf,'PDE_sol.png')%Save figure as png in current directory 

%run a second loop that does not include the initial condition to get a 
%better view of the long term behaviour. 
%Plotting variables 
figure(2); 
hold on; 
axis([0 L -inf inf]); 
xlabel('x'); 
ylabel('u(x,t)'); 
for i=2:tgrid 
    plot(x,u(i,:),'linewidth',4); 
end 
saveas(gcf,'PDE_sol_without_inital.png')%Save figure as png in current directory 

%Create a gif verison of figure 2 
figure(3); 
axis([0 L -inf inf]); 
xlabel('x'); 
ylabel('u(x,t)'); 
filename = 'PDE_sol.gif'; 
for i=2:tgrid 
    plot(x,u(i,:),'linewidth',4); 
    drawnow 
    frame = getframe(1); 
    im = frame2im(frame); 
    [imind,cm] = rgb2ind(im,256); 

    if i == 2; 
     imwrite(imind,cm,filename,'gif', 'Loopcount',inf); 
    else 
     imwrite(imind,cm,filename,'gif','WriteMode','append'); 
    end 
end 

Выход GIF, что я получаю

this

, которая явно не анимированные.

Примечание: Если вы считаете, что есть лучшее место для публикации этого вопроса, пожалуйста, направьте меня на него. Поскольку моя проблема связана с языком программирования MATLAB, а не с математикой, я думал, что это будет лучшее место для публикации моего вопроса.

ответ

3

Первый ввод getframe - это дескриптор figure, который вы хотите сделать снимок экрана. Как вы его написали, вы захватываете цифру , которая на самом деле относится к первой фигуре, которую вы создаете, которую вы не обновляете в своем цикле.

Вы назначили числовой дескриптор на рисунок, который вы создаете перед последней петлей так что вы хотите сказать getframe использовать что фигуру вместо этого.

Кроме того, я бы создал один объект объекта и обновил XData и YData, а не постоянно создавал новые объекты сюжета. Проблема с вызовом plot заключается в том, что он медленный И полностью сбрасывает все ваши настройки axes, такие как ярлыки x и y, а также пределы x и y.

% Store the handle to the figure in hfig 
hfig = figure(3); 

% Create the initial plot object 
hplot = plot(NaN, NaN, 'LineWidth', 4); 

axis([0 L 0 2]); 
xlabel('x'); 
ylabel('u(x,t)'); 

filename = 'PDE_sol.gif'; 

for i=2:tgrid 
    % Update the plot appearance 
    set(hplot, 'XData', x, 'YData', u(i,:)); 
    drawnow 

    % Get a screenshot of THIS figure 
    frame = getframe(hfig); 
    im = frame2im(frame); 

    [imind,cm] = rgb2ind(im,256); 

    if i == 2; 
     imwrite(imind,cm,filename,'gif', 'Loopcount',inf); 
    else 
     imwrite(imind,cm,filename,'gif','WriteMode','append'); 
    end 
end 

enter image description here

+0

Это помогло решить мою главную проблему. Как исправить размеры оси (по вертикали) и пометить ось? – AzJ

+0

@AzJ Обновлено, чтобы показать, как вы можете это сделать. – Suever