Creating a movie from a figure with multiple subplots
    23 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
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
0 comentarios
Respuestas (1)
  Kevin Phung
      
 el 21 de Dic. de 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
Ver también
Categorías
				Más información sobre Convert Image Type en Help Center y File Exchange.
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

