Creating a movie from a figure with multiple subplots

13 vues (au cours des 30 derniers jours)
Keegan Karbach
Keegan Karbach le 21 Déc 2022
Modifié(e) : Keegan Karbach le 22 Déc 2022
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

Réponses (1)

Kevin Phung
Kevin Phung le 21 Déc 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 commentaire
Keegan Karbach
Keegan Karbach le 21 Déc 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...

Connectez-vous pour commenter.

Catégories

En savoir plus sur Blue dans Help Center et File Exchange

Produits


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by