Filter löschen
Filter löschen

Creating a movie from a figure with multiple subplots

32 Ansichten (letzte 30 Tage)
Keegan Karbach
Keegan Karbach am 21 Dez. 2022
Bearbeitet: Keegan Karbach am 22 Dez. 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

Antworten (1)

Kevin Phung
Kevin Phung am 21 Dez. 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 Kommentar
Keegan Karbach
Keegan Karbach am 21 Dez. 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...

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Animation finden Sie in Help Center und File Exchange

Produkte


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by