如何在MATLAB循环中实现无闪烁动态绘图并修正子图X轴?
MATLAB动态绘图优化方案
问题背景
我尝试用以下MATLAB代码在for循环中实现动态绘图:
clc, clear, close all t = 0:0.00001:0.8; iter = 1; for f=0:0.5:50 yu = sin(2*pi*f*t); yd = -1*[zeros(1,6666) yu]; yd = yd(1:numel(yu)); yu = yu(8150:end); yd = yd(8150:end); y(iter) = sum(abs(yu+yd))./(numel(yd)); y2 = yu+yd; hp = subplot(211), plot(yu), hold on, plot(yd);title(num2str(f)) ylim([-1.5 1.5]) pause(0.1) drawnow, delete(hp); iter = iter+1; subplot(212), plot(y,'k'), hold on; drawnow, xlim([0 100]), ylim([0 2]) end
但遇到两个问题:
- 顶部子图每次迭代都会闪烁,无法制作平滑动画;
- 底部子图的X轴希望使用
f=0:0.5:50的序列,而非当前迭代次数。
优化后的代码
clc, clear, close all t = 0:0.00001:0.8; f_list = 0:0.5:50; % 提前定义完整频率序列 num_iter = length(f_list); y = zeros(1, num_iter); % 预分配内存,提升运行效率 % 初始化绘图环境,开启双缓冲消除闪烁 figure('DoubleBuffer','on') % 配置顶部子图和绘图对象 hp1 = subplot(211); hold(hp1, 'on') ylim(hp1, [-1.5 1.5]) xlabel(hp1, '样本点') ylabel(hp1, '幅值') % 初始化两条曲线(先绘制空数据,后续仅更新数据) h_yu = plot(hp1, nan, 'b'); h_yd = plot(hp1, nan, 'r'); title_handle = title(hp1, ['频率: ', num2str(f_list(1))]); % 配置底部子图和绘图对象 hp2 = subplot(212); hold(hp2, 'on') xlim(hp2, [f_list(1) f_list(end)]) % 设置X轴为频率范围 ylim(hp2, [0 2]) xlabel(hp2, '频率 (Hz)') ylabel(hp2, '平均绝对值和') h_y = plot(hp2, nan, 'k'); % 初始化底部曲线 for iter = 1:num_iter f = f_list(iter); % 计算原始数据(逻辑保持不变) yu = sin(2*pi*f*t); yd = -1*[zeros(1,6666) yu]; yd = yd(1:numel(yu)); yu = yu(8150:end); yd = yd(8150:end); y(iter) = sum(abs(yu+yd))./(numel(yd)); % 更新顶部子图的曲线数据和标题 set(h_yu, 'YData', yu) set(h_yd, 'YData', yd) set(title_handle, 'String', ['频率: ', num2str(f)]) % 更新底部子图:用频率序列作为X轴,逐步绘制数据 set(h_y, 'XData', f_list(1:iter), 'YData', y(1:iter)) drawnow % 刷新绘图 pause(0.1) end
关键修改点说明
- 消除闪烁:
- 开启窗口双缓冲:
figure('DoubleBuffer','on'),MATLAB在后台完成绘制后再显示画面,彻底避免闪烁; - 提前创建所有绘图对象(子图、曲线、标题),循环中仅更新数据而非重复创建/删除元素,减少重绘开销。
- 开启窗口双缓冲:
- 底部子图X轴改为频率序列:
- 提前定义
f_list存储所有频率值,循环更新底部曲线时,直接使用f_list(1:iter)作为X轴数据; - 初始化时设置底部子图X轴范围为频率的起止值,保证坐标轴稳定。
- 提前定义
- 额外优化:预分配
y数组内存,避免循环中动态扩容,提升代码运行效率。
内容的提问来源于stack exchange,提问作者user3482383
相关产品推荐
相关产品推荐

