Increase plot speed in MATLAB
34 次查看(过去 30 天)
显示 更早的评论
I'm trying to do an "animation" of a simple, straight line moving in a figure.
I start a timer with a fixed rate period of 0.01 s and the 'TimerFcn' calls a function called MoveLineLoop. This does some calculations before it calls my PlotLine function.
So in essense I have something like:
function MoveLineLoop(...)
tic
%%
%% Calculate y1, alpha, LineLength etc...
%%
[MyLine,x2,y2] = PlotLine(y1,alpha,LineLength,MyLine,ax);
toc
end
Where
function [MyLine,x2,y2] = PlotLine(y1,alpha,LineLength,MyLine,ax)
format compact
format short
x2 = LineLength*cosd(alpha);
y2 = y1 + LineLength*sind(alpha);
%plotting the Line
try
set(MyLine(1),"XData",[0 x2],"YData",[y1 y2]); %If already plotted just adjust position
catch
MyLine = line(ax,[0 x2], [y1 y2],'Color',[0 0 0],'LineWidth', 20, 'Marker', '+', 'MarkerSize', 1, 'MarkerEdgeColor', 'r'); %First plot
end
%drawnow
end
So with tic and toc I think I'm measuring the whole process including the update of the line-plot.
If I look in the command window it looks as if each iteration of the MoveLineLoop constantly takes less than 0.005 s which should mean that it manage to update my lineplot before the next timer tic (0.01s).
Elapsed time is 0.000577 seconds.
Elapsed time is 0.000634 seconds.
Elapsed time is 0.000562 seconds.
Elapsed time is 0.004895 seconds.
Elapsed time is 0.000851 seconds.
Elapsed time is 0.000563 seconds.
Elapsed time is 0.001068 seconds.
Elapsed time is 0.000824 seconds.
Elapsed time is 0.000933 seconds.
Elapsed time is 0.000944 seconds.
Elapsed time is 0.000591 seconds.
Elapsed time is 0.001045 seconds.
Elapsed time is 0.000757 seconds.
When I look at the figure it is obvious however that there is a huge lag in the line updates, so the line continues to move several seconds after the last loop is executed.
If I add the drawnow-command the time of the loop increases and perhaps this shows the true time it takes for the loop including the change of the line?
Elapsed time is 0.036258 seconds.
Elapsed time is 0.035916 seconds.
Elapsed time is 0.097260 seconds.
Elapsed time is 0.094104 seconds.
Elapsed time is 0.192176 seconds.
Elapsed time is 0.107693 seconds.
Elapsed time is 0.103099 seconds.
Elapsed time is 0.095233 seconds.
Elapsed time is 0.108471 seconds.
Is it possible to increase the plot-speed in MATLAB somehow? I have a machine with a powerfull GPU.
0 个评论
采纳的回答
Bruno Luong
2024-3-18
编辑:Bruno Luong
2024-3-18
Try to look at animatedline command
Also look at drawnow with or without limitedrate option, it somewhat has certain effect, even it is o clear to me what is the best. It seems to me if you want to update faster than the plot command can handle then you should use limitedrate, otherwise it is better to disable it.
Usually avoid using marker and long data (it's not clear what size of you alpha vector), say 1000 points is usualy OK.
Also most of the monitor refresh at 60 Hz, there is no point to stress the update at 100 Hz. In the pass I can reah 40 Hz refresh, but it is still fragile. Better to have lower refresh rate and no latency. Try to experiment by changing update rate.
Makesure to use opengl hardware and up-to-date graphic driver on your computer.
I don't know what is the situation now but in the pass working legacy axes/figure is faster than uiaxes/uifigure.
0 个评论
更多回答(2 个)
DGM
2024-3-18
I think Yair's comment is probably a good start, though perhaps the significance of certain parts have changed over time:
I don't know what your inputs are or how you're generating them, but as a rule, try to keep as much stuff as you can out of the short part of the loop. Avoid dumping things to console or setting the console format inside the loop. That's just wasting time. Avoid needing to update any more graphics objects as you can.
You should probably be using drawnow(), but you can still expect the actual interval to vary sporadically. You'll just have fewer cases where the frames are simply skipped.
You can play around with different renderers, but the effects will depend on your graphics drivers and whatever else is in the figure. For something this simple, with my garbage hardware, the painters renderer was significantly faster, but on the forum, I see no significant difference; you might see different results. Using 'doublebuffer' only applies to the 'painters' renderer, but I see no observable difference in time either on my hardware or here.
Here are two simple tests using vectors for y1, alpha, and LineLength. Feel free to see whether there's any noticeable changes in timing on your system.
% parameters
ax = gca;
MyLine = 0;
nframes = 100;
y1 = linspace(-10,10,nframes);
alpha = linspace(0,360,nframes);
LineLength = linspace(1,10,nframes);
% keep axes a constant size
% set things to manual to avoid making changes in the loop
xlim([-10,10])
ylim([-10,10])
set(gca,'xlimmode','manual')
set(gca,'ylimmode','manual')
% set the renderer settings
set(gcf,'renderer','painters') % 'painters' or 'opengl'
set(gcf,'doublebuffer','off') % this only applies to 'painters'
% 7.3ms painters, regardless of doublebuffer
% 18ms opengl (doublebuffer doesn't apply)
% TEST 1
% test the loop calculating one value at a time
tic
for k = 1:nframes
[MyLine,x2,y2] = PlotLine(y1(k),alpha(k),LineLength(k),MyLine,ax);
end
tt = toc;
tt/nframes % average frame time
% TEST 2
% test the loop calculating all x,y values first
% this is only a tiny bit faster, and only in certain cases
tic
x2 = LineLength.*cosd(alpha);
y2 = y1 + LineLength.*sind(alpha);
for k = 1:nframes
MyLine = PlotLineBetter(x2(k),y1(k),y2(k),MyLine,ax);
end
tt = toc;
tt/nframes % average frame time
% THE TEST FUNCTIONS
function [MyLine,x2,y2] = PlotLine(y1,alpha,LineLength,MyLine,ax)
x2 = LineLength*cosd(alpha);
y2 = y1 + LineLength*sind(alpha);
try
set(MyLine(1),"XData",[0 x2],"YData",[y1 y2]); %If already plotted just adjust position
catch
MyLine = line(ax,[0 x2], [y1 y2],'Color',[0 0 0],'LineWidth', 2, 'Marker', '+', 'MarkerSize', 1, 'MarkerEdgeColor', 'r'); %First plot
end
drawnow
end
function MyLine = PlotLineBetter(x2,y1,y2,MyLine,ax)
try
set(MyLine(1),"XData",[0 x2],"YData",[y1 y2]); %If already plotted just adjust position
catch
MyLine = line(ax,[0 x2], [y1 y2],'Color',[0 0 0],'LineWidth', 2, 'Marker', '+', 'MarkerSize', 1, 'MarkerEdgeColor', 'r'); %First plot
end
drawnow
end
0 个评论
Pratyush
2024-3-18
Hi Quist,
To increase the plot speed in MATLAB, especially for real-time updates like in your animation, consider the following strategies:
- Use smaller line widths, simplify or remove markers, and limit the number of data points.
- Stick to efficient functions like "plot" and "line".
- Enable "DoubleBuffer" for the figure to reduce flicker and ensure you're only updating parts of the plot that change.
- For computational bottlenecks, utilize "gpuArray" to offload heavy computations to the GPU.
- Use MATLAB's profiler to identify and optimize bottlenecks outside the plotting commands.
- Verify MATLAB is using your GPU for rendering with "opengl info" and troubleshoot if necessary.
- If feasible, slowing down the update rate by increasing the timer period can reduce lag.
Implementing these strategies can help mitigate the lag in real-time plot updates, though the effectiveness varies based on the specific scenario and system configuration. Hope this helps.
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Graphics Performance 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!