Creating a movie from a figure with multiple subplots

21 views (last 30 days)
Hello there! I'm trying to record a movie from a figure with 4 subplots that change over a sequence. The code below runs and shows the correct figure, but when I attempt to view the movie, it only shows a black screen and finally the completed figure at the last frame. Any help would be much appreciated!
Edit: I've attached a working test file and changed the code to define the axes outside the loop. Now I get an error message:
"All 'cdata' fields with a specified 'colormap' must be two dimensional."
I have used this script to create videos that only contain one axis, so I'm sure it's something I'm missing using multiple axes...
% Set up the movie structure.
% Preallocate movie, which will be an array of structures.
% First get a cell array with all the frames.
numberOfFrames = seq_length;
hFigure = figure;
allTheFrames = cell(numberOfFrames,1);
[vidHeight, vidWidth] = size(sequence(:,:,1));
allTheFrames(:) = {zeros(vidHeight, vidWidth, 3, 'uint8')};
% Next get a cell array with all the colormaps.
allTheColorMaps = cell(numberOfFrames,1);
allTheColorMaps(:) = {zeros(256, 3)};
% Now combine these to make the array of structures.
myMovie = struct('cdata', allTheFrames, 'colormap', allTheColorMaps);
set(gcf, 'renderer', 'zbuffer');
ax1 = subplot(2,2,1);
ax2 = subplot(2,2,2);
ax3 = subplot(2,2,3);
ax4 = subplot(2,2,4);
for i = 1:seq_length
cla reset
imshow(sequence_ramp(:,:,i),[],'Parent',ax1);
caxis(ax1,[0, 255]);
title(ax1,caption)
surf(ax2,x,y,sequence_ramp(:,:,i),'EdgeColor','none');
caxis(ax2,[0, 255]);
zlim(ax2,[0, 255]);
imshow(sequence_good(:,:,i),[],'Parent',ax3);
caxis(ax3,[0, 255]);
title(ax3,caption + " After AOC")
ylh = ylabel(ax3,{"Alpha " + num2str(alpha),"qThresh " + num2str(qThresh)});
ylh.Rotation = 0;
ylh.Position(1) = ylh.Position(1) - 25;
surf(ax4,x,y,sequence_good(:,:,i),'EdgeColor','none');
zlim(ax4,[0, 255]);
caxis(ax4,[0, 255]);
colormap('turbo');
drawnow
myMovie(frameIndex) = getframe(gcf);
end
% Save movie as file
promptMessage = sprintf('Do you want to save this movie to disk?');
titleBarCaption = 'Continue?';
button = questdlg(promptMessage, titleBarCaption, 'Yes', 'No', 'Yes');
if strcmpi(button, 'yes')
% Get the name of the file that the user wants to save.
% Note, if you're saving an image you can use imsave() instead of uiputfile().
startingFolder = pwd;
defaultFileName = {'*.avi';'*.mp4';'*.mj2'}; %fullfile(startingFolder, '*.avi');
[baseFileName, folder] = uiputfile(defaultFileName, 'Specify a file');
if baseFileName == 0
% User clicked the Cancel button.
return;
end
fullFileName = fullfile(folder, baseFileName);
% Create a video writer object with that file name.
% The VideoWriter object must have a profile input argument, otherwise you get jpg.
% Determine the format the user specified:
[folder, baseFileName, ext] = fileparts(fullFileName);
switch lower(ext)
case '.jp2'
profile = 'Archival';
case '.mp4'
profile = 'MPEG-4';
otherwise
% Either avi or some other invalid extension.
profile = 'Uncompressed AVI';
end
writerObj = VideoWriter(fullFileName, profile);
open(writerObj);
% Write out all the frames.
numberOfFrames = length(myMovie);
for frameNumber = 1 : numberOfFrames
writeVideo(writerObj, myMovie(frameNumber));
end
close(writerObj);
% Display the current folder panel so they can see their newly created file.
cd(folder);
filebrowser;
message = sprintf('Finished creating movie file\n %s.\n\nDone with demo!', fullFileName);
uiwait(helpdlg(message));
else
uiwait(helpdlg('Done with demo!'));
end

Answers (1)

Kevin Phung
Kevin Phung on 21 Dec 2022
A bit hard to test your code without sample files, but I would start by defining axes handles outside of your for-loop, along with anything else that you don't intend on changing. This would allow your loop to run more efficiently. for example, you can assign a handle to your second subplot
ax2 = subplot(2,2,2)
and plot directly to it within the for loop
for i = 1:seq_length
surf(ax2,x,y,sequence_ramp(:,:,i),'EdgeColor','none');
end
  1 Comment
Keegan Karbach
Keegan Karbach on 21 Dec 2022
I've changed the code to define the axes outside of the loop and packaged the file to attach here. When I attempt to save the figure with subplots as a movie, I get the error:
"All 'cdata' fields with a specified 'colormap' must be two dimensional."
I've used the same script to save movies with just one single axis, so I'm assuming that the problem is with the multiple axes...

Sign in to comment.

Categories

Find more on Animation in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!