How can I make a gif using subplots and avoid an error in function wgifc?

Hi everyone,
I am trying to generate a gif of my results over different timestep using the following procedure:
h = figure;
filename = 'testnew51.gif';
axis tight manual % this ensures that getframe() returns a consistent size
for t=10:10:100 % t is the percent number in the file name
subplot(121)
fn = "T_timestep_"+t+"_precent.bin";
fid = fopen(fn); % file for t-th step
nx = fread(fid,1,'int32');
ny = fread(fid,1,'int32');
T = reshape(fread(fid,nx*ny,'double'),nx,ny);
fclose = (fid);
contourf(T')
colorbar;
subplot(122)
fn = "S_timestep_"+t+"_precent.bin";
fid = fopen(fn); % file for t-th stepfid = fopen('S.bin');
nx = fread(fid,1,'int32');
ny = fread(fid,1,'int32');
S = reshape(fread(fid,nx*ny,'double'),nx,ny);
fclose = (fid);
contourf(S')
colorbar;
drawnow
% Capture the plot as an image
frame = getframe(h);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
% Write to the GIF File
if t == 1
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
pause(0.2)
end
However I get the error:
Error using wgifc
Can only append to GIF89a format GIFs.
Error in writegif (line 306)
wgifc(mat, map, filename,writemode,disposalmethod,delaytime,...
Error in imwrite (line 566)
feval(fmt_s.write, data, map, filename, paramPairs{:});
Error in matlab_run (line 34)
imwrite(imind,cm,filename,'gif','WriteMode','append');
How can I resulve that? Or is there a better way to generate a gif?
And also how can I scale the x-axis and y-axis of the subplots in respect of an scaled entity of nx and ny respectively? So that the ratio of the subplots are representing my original grid.
Thanks a lot already in advance for all your help and time.

 채택된 답변

Walter Roberson
Walter Roberson 2021년 11월 17일

0 개 추천

Your t==1 test is never successful because your for loop is t=10:10:100 and so starts with 10 instead of 1

추가 답변 (1개)

Jan
Jan 2021년 11월 10일
편집: Jan 2021년 11월 10일
The calling style "subplot(121)" is outdated for over 20 years now. Use subplot(1, 2, 1) instead.
You can simplify:
reshape(fread(fid,nx*ny,'double'),nx,ny)
to
fread(fid, [nx, ny],'double')
This line redefines the command fclose as a variable:
fclose = (fid);
You want this instead:
fclose(fid);
I guess, that the number of unclosed files stops opening a new file, because the number of simultaneously open files is limited by the operating system. The error message would be misleading, if this is true.
Use fclose('all') in the command window to clean up the already open files or restart Matlab.
how can I scale the x-axis and y-axis of the subplots in respect of an scaled entity of nx and ny respectively? So that the ratio of the subplots are representing my original grid.
I'm not sure, what this means. Maybe:
axesH = subplot(1, 2, 1);
axis(axesH, 'equal');

댓글 수: 18

Hi thanks foryour help and inputs. I changed the code now accordingly however I still get an error:
Error using wgifc
Can only append to GIF89a format GIFs.
Error in writegif (line 306)
wgifc(mat, map,
filename,writemode,disposalmethod,delaytime,...
Error in imwrite (line 566)
feval(fmt_s.write, data, map, filename,
paramPairs{:});
Error in matlab_run (line 34)
imwrite(imind,cm,filename,'gif','WriteMode','append');
The code is now:
h = figure;
filename = 'testnew51.gif';
axis tight manual % this ensures that getframe() returns a consistent size
for t=10:10:100 % t is the percent number in the file name
subplot(1,2,1)
fn = "T_timestep_"+t+"_precent.bin";
fid = fopen(fn); % file for t-th step
nx = fread(fid,1,'int32');
ny = fread(fid,1,'int32');
T = fread(fid, [nx, ny],'double');
fclose(fid);
contourf(T')
colorbar;
subplot(1,2,2)
fn = "S_timestep_"+t+"_precent.bin";
fid = fopen(fn); % file for t-th stepfid = fopen('S.bin');
nx = fread(fid,1,'int32');
ny = fread(fid,1,'int32');
S = fread(fid, [nx, ny],'double');
fclose(fid);
contourf(S')
colorbar;
drawnow
% Capture the plot as an image
frame = getframe(h);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
% Write to the GIF File
if t == 1
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
pause(0.2)
end
I have also used cose('all') as sujested.
Which Matlab version are you using?
The most recent version.
imwrite() is not able to write out a different colormap for each frame of a GIF. You need to work out a colormap first, and use rgb2ind() to map each frame based upon that colormap.
If you instead write out RGB images without a colormap, then imwrite() will determine a colormap based upon the first frame, and will convert all remaining frames to that colormap.
Thank you very much vor your help Walter Roberson. However I am still a bit confused on how to implent your sucession in the code. Can you claryfy a bit how I need to change the code in order to get it working? Sorry for this but I just get quite what I need to change.
Hmmm, it is not obvious at the moment. Could you test the following?
And just in case... please make sure that the output file does not already exist.
h = figure();
filename = 'testnew51.gif';
axis tight manual % this ensures that getframe() returns a consistent size
for t = 1 : 10
surf(rand(20,20));
drawnow();
frame = getframe(h);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
% Write to the GIF File
if t == 1
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
end
[images, cmap] = imread(filename, 'Frames', 'all');
size(images)
ans = 1×4
433 577 1 10
size(cmap)
ans = 1×2
128 3
Your code is working fine on my laptop and the gif is generated and works also. I get however different outputs then yours:
[images, cmap] = imread(filename, 'Frames', 'all');
size(images)
ans =
840 1120 1 10
size(cmap)
ans =
256 3
Is this to be expected? And why does work your code but mine does not?
The system that I ran the code on has a small display.
Ok thaks a lot for the clarifiaction.
Do you know what the mistake in my code might be as I still get the same error?
I've tried it with different colormaps for the appended images and different sizes, but cannot reproduce the error message.
Did you restart Matlab and the computer already? Did you examing the created GIF file with an image viewer and can you confirm that it has the 89a format?
David Kaeser
David Kaeser 2021년 11월 13일
편집: David Kaeser 2021년 11월 13일
Ok that is weird. Yes I have restarted the computer and Malab already and nothing changed. The thing is there is not even a file created...
Do you have write permissions in tis folder?
Yes I should have permission to write in this folder. I was also able to run the example code from Walter Roberson.
This is too strange. Think twice.
Set a breakpoint in this line:
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
After this command ran, check, if the file was created:
isfile(fullfile(cd, filename))
If the file is not created, but you do not get an error message, the most logical explanation is an attack of extraterrestrials.
First of all thanks for all your help and time. Unfortunatly however is still does not work. If I set the breakpoint in line of :
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
I still get the error and an output of logical 0 for the code:
isfile(fullfile(cd, filename))
However if I put the breakpoint in the line:
imwrite(imind,cm,filename,'gif','WriteMode','append');
and the code stops but still now file is created. What I just can't understand is why it works with xx's code but not with mine.... I run it in exactly the same order ect. Do I still need to distribute specific write permissions?I currently have the code localized in a folder on my desktop from a windows machine. So I think maybe we should slowly start looking for aliens....
Or could I maybe bypass this problem if I would make an mpg or mov file?
To check: are you doing the isfile() before you do the imwrite 'loopcount' call, or after that call? The file is not expected to exist until after the call.
I tired it as statement just after the "loopcount" call in the script and as well outside of the script after an unsucessful run. When I tried as statement in the script the error message already appeared and the statment is not executed. Outside of the script I get a zero value.
I discouvered however something strange now. If I run your code first Walter Roberson and then my code with the same filename the error disaspears. I get then an gif with the results first from the first code and in the same gif the results from my code. How can make sure that I get only my results in the gif?

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Data Import and Analysis에 대해 자세히 알아보기

제품

릴리스

R2021b

질문:

2021년 11월 10일

댓글:

2021년 11월 17일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by