Main Content

Improve Graphics Performance

When you create data visualizations using MATLAB® graphics functions, you can use certain techniques in your code to increase performance. This topic covers some of these techniques, including strategies to speed up long-running animations, to quickly update plot data, and to create visualizations that respond smoothly to user input. Use any techniques that are helpful for the type of graphics that you create.

Improve Graphics Update Speed

When you update an existing plot or other graphics object, you can improve the performance of your code by updating only the data that changes, instead of recreating all of the data from scratch.

For example, this code updates an axes object that contains both a surface plot and a single marker. At each stage of the update, only the marker changes position. All of the data associated with the surface plot and many of the marker properties remain the same at each step. Rather than updating all the data by calling the surf and plot3 functions multiple times, update only the properties that control the position of the marker object.

[sx,sy,sz] = peaks(500);
nframes = 490;

surf(sx,sy,sz,"EdgeColor","none")
hold on
m = plot3(sx(1,1),sy(1,1),sz(1,1),"o", ...
    "MarkerFaceColor","red", ...
    "MarkerSize",14);
hold off

for t = 1:nframes
    m.XData = sx(t+10,t);
    m.YData = sy(t,t+10);
    m.ZData = sz(t+10,t+10)+0.5;
    drawnow
end

Improve Image Loading Speed

Since R2022b

When you work with an image, you can set the MaxRenderedResolution property to control the maximum resolution MATLAB uses to display the larger dimension of the image. The smaller dimension adjusts to preserve the aspect ratio. The value you specify affects the on-screen display, but it does not affect the image data, which is stored in the CData property of the image.

Specify "none" to display the image at full resolution. Specify a number to limit the size of the displayed image. Larger numbers (and "none") provide higher quality images, but the initial images might take longer to render. Smaller numbers provide downsampled images, but they render faster.

In general, images render faster when you specify a value that is smaller than the largest image dimension of the original image. However, if you specify a value that is only one or a few pixels smaller, the initial rendering of that image might take longer than rendering it at full resolution.

For example, read peppers.png, which is a 384-by-512 RGB image. Then call the imagesc function to display the image using 128 pixels along the larger dimension. The smaller dimension scales down to 96 pixels to maintain the original aspect ratio.

imdata = imread("peppers.png");
imagesc(imdata,"MaxRenderedResolution",128)

peppers.png displayed at a resolution of 96-by-128 pixels

Identify Bottlenecks in Your Code

Use the Profiler to identify the functions that contribute the most time to the execution of your code. You can then evaluate those functions for possible performance improvements.

For example, create a scatter plot of 10-by-500 element arrays using the myPlot function.

function myPlot
x = rand(10,500);
y = rand(10,500);
scatter(x,y,"blue");
end

Use the Profiler to time the execution of the myPlot function. The code takes about 2.7 seconds to execute.

profile on
myPlot
profile viewer

Flame graph in the profile summary. The myPlot function accounts for 99.9% of the code execution time and takes 2.736 seconds to run.

Because the x and y arrays contain 500 columns of data, the scatter function creates 500 Scatter objects. In this case, you can plot the same data by creating one object with 5000 data points instead.

function myPlot
   x = rand(10,500);
   y = rand(10,500);
   scatter(x(:),y(:),"blue");
end

Profile this updated code. The function now takes less than 0.3 second to execute.

profile on
myPlot
profile viewer

Flame graph in the profile summary. The myPlot function accounts for 98.5% of the code execution time and takes 0.262 second to run.

To learn more about using the Profiler, see Profile Your Code to Improve Performance.

Improve Performance of Long-Running Animations

To improve the performance of long-running animations, consider using drawnow limitrate instead of drawnow to display updates on the screen. Both commands update the figure display, but drawnow limitrate limits the number of updates to 20 frames per second. As a result, animations can appear faster.

Some scenarios in which using drawnow limitrate can improve animation performance include:

  • Animations in which it is important to see the most up-to-date frame, such as plots of real-time simulation data

  • Animations in which the number of frames per second is large and it is not necessary to display every frame

For example, this code creates an animated line and adds 50,000 data points to the line in a loop. Using drawnow limitrate in the loop limits the number of times the display is updated, which results in a faster animation than performing an update each time through the loop.

h = animatedline;
axis([0 4*pi -1 1])
x = linspace(0,4*pi,50000);
 
for k = 1:length(x)
    y = sin(x(k));
    addpoints(h,x(k),y);
    drawnow limitrate
end

Provide Smooth and Responsive Axes Interactions

When you display data in an axes object, you can configure interactions with the data, such as dragging to pan and scrolling to zoom. In general, use and configure the built-in interactions that MATLAB provides. The built-in axes interactions are optimized to respond smoothly to user input and can provide a more responsive experience than if you implement a custom interactivity callback such as a WindowScrollWheelFcn.

The built-in interactions depend on the contents of the axes but typically include scrolling to zoom, dragging to pan or rotate, and hovering or clicking to display data tips. You can enable these interactions by calling the enableDefaultInteractivity function. In addition, you can customize the built-in interactions for a specific chart by setting the Interactions property of the axes object. For more information about enabling and customizing built-in interactions, see Control Chart Interactivity.

If a fast startup time is more important for your code than enabling axes interactions, instead consider disabling the built-in axes interactions. This action will cause the axes object to display sooner. You can disable the built-in interactions by calling the disableDefaultInteractivity function.

Related Topics