Octave环境下信号频率图顶部峰值标注的实现方案求助
解决Octave中信号峰值标注问题
你的代码主要有三个问题:
max()返回的t是数组索引,不是实际时间值,直接用它做x坐标会导致标注位置错误- 删除数组元素会导致后续循环的索引错位,无法正确找到下一个峰值
annotation默认使用归一化坐标,和你的数据坐标不匹配,导致标注显示在不可见区域
以下是可直接运行的代码,假设你有时间数组time_vec和对应的频率数组freq_vec:
% 示例数据(替换成你的time_vec和freq_vec即可) time_vec = linspace(0, 10, 1000); freq_vec = sin(time_vec) + 0.5*sin(3*time_vec) + rand(size(time_vec))*0.2; freq_vec(200) = 2; % 手动添加峰值示例 freq_vec(600) = 1.8; freq_vec(800) = 1.5; % 绘制原始曲线 plot(time_vec, freq_vec, 'b-', 'LineWidth', 1); hold on; % 保持画布,用于叠加标记和标注 % 复制频率数组,避免修改原数据 copy_freq = freq_vec; num_peaks = 5; % 要标注的峰值数量 for j = 1:num_peaks % 找到当前最大值及其索引 [max_freq, peak_idx] = max(copy_freq); % 获取对应的实际时间值 peak_time = time_vec(peak_idx); % 添加红色小圆点标记峰值 plot(peak_time, max_freq, 'ro', 'MarkerSize', 6, 'MarkerFaceColor', 'r'); % 添加带箭头的频率标注,使用数据坐标匹配绘图系统 annotation('textarrow', ... [peak_time, peak_time], ... [max_freq, max_freq - 0.3], ... % 箭头向下偏移0.3个数据单位 'String', num2str(max_freq, '%.2f'), ... % 保留两位小数 'Units', 'data', ... 'FontSize', 10, ... 'Color', 'darkred'); % 将当前峰值设为极小值,避免下次重复选中 copy_freq(peak_idx) = -inf; endfor hold off; xlabel('时间'); ylabel('频率'); title('信号频率随时间变化曲线(标注前5个峰值)');
关键修改说明:
- 通过
peak_idx获取最大值索引,再映射到实际时间数组time_vec,确保标注位置准确 - 不删除数组元素,而是将已找到的峰值设为
-inf,既避免重复选中,又保持数组长度不变,防止索引错位 - 给
annotation添加'Units', 'data'参数,让标注坐标与绘图坐标系统一致,确保标注显示在可视区域 - 用
hold on维持画布状态,保证标记和标注能叠加在原始曲线上
内容的提问来源于stack exchange,提问作者user249018
相关产品推荐
相关产品推荐

