Is there a faster way to save plots (Figures) to a Report than GetSnapshotImage?

9 views (last 30 days)
I am plotting hundreds of plots (figures) to a MATLAB PDF report generator in a for loop like below:
for i =1:500
figure('visible','off'); %don't display the figure on screen
eval(sprintf(['plot%d = Figure(plot(t,data%d));'],i,i)) %save each figure into individual variable
eval(sprintf(['plot%d_Image = Image(getSnapshotImage(plot%d, rpt),i); %takes screenshot of plots (slow when large # of plots)
The problem is strictly a timing issue with getSnapShotImage taking awhile when there are alot of figures. Since I am saving so many figures to the report, getSnapShotImage takes a long time to manually open the figures and screenshot it. Is there a faster way to do this that takes much less time such that I can avoid getSnapShotImage and replace it with a faster method?I am saving hundreds of plots to a PDF report using the report editor.
I have tried using something such as add(rpt, figure%d) but this did not work.
Thank you.

Accepted Answer

Madheswaran
Madheswaran on 6 Sep 2024
Hello,
To address the performance issues you're encountering, let's first identify which part of your code is consuming the most time. I recommend using the MATLAB Profiler app for this task.
As you can see from the profiler summary, the ‘getSnapshotImage’ function is the primary bottleneck. Additionally, creating a new figure for each iteration is another source of overhead.
Below, I've outlined some modifications to optimize your code:
num_plots = 10;
t = 0:0.1:10;
import mlreportgen.report.*
import mlreportgen.dom.*
rpt = Report('myreport', 'pdf');
% Create a single figure object to be reused
fig = figure('visible', 'off');
% Preallocate cell array for plot images and filenames
plot_images = cell(1, num_plots);
filenames = cell(1, num_plots);
% Generate plots
for i = 1:num_plots
data = sin(i*t); % Generate some sample data
% Reuse the figure object
clf(fig);
plot(t, data);
title(sprintf('Plot %d', i));
% Save figure directly to image file
filenames{i} = sprintf('plot_%d.png', i);
print(fig, filenames{i}, '-dpng');
img = Image(filenames{i});
img.Height = '3in';
img.Width = '4in';
plot_images{i} = img;
end
% Add images to the report
add(rpt, plot_images);
% Close the figure and report
close(fig);
close(rpt);
% Delete the temporary image files
for i = 1:num_plots
if exist(filenames{i}, 'file')
delete(filenames{i});
end
end
For 10 iterations, including the creation of sample data, the optimized code executes in ~2.7 seconds, compared to approximately 6 seconds for the original code.
The modifications I implemented is as follows:
  • I have used ‘print’ function instead of ‘getSnapshotImage’ to save each plot directly as a PNG file, which is more efficient.
  • A single figure object is reused across all iterations, reducing overhead.
Additionally, it is advisable to avoid using ’eval’ for dynamic variable naming, as it can lead to inefficiencies. For more information, please refer to this link: https://mathworks.com/matlabcentral/discussions/tips/849901-tutorial-why-variables-should-not-be-named-dynamically-eval/2588356
Refer to the following MathWorks documentation for the more information:
  1. print - https://mathworks.com/help/matlab/ref/print.html
  2. Image - https://mathworks.com/help/rptgen/ug/image.html
  3. Profiler App - https://mathworks.com/help/matlab/ref/profiler-app.html
Hope this helps!

More Answers (0)

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!