You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将imshow的X轴索引替换为实际频率(kHz)?

解决方案:将FFT热力图X轴从索引改为实际频率(kHz)

核心思路

要把X轴从默认的数组索引替换为实际频率,关键是利用你已经计算好的f(频率数组),截取前半部分(和你显示的FFT幅度数据对应)并转换为kHz单位,再将这个频率值绑定到X轴刻度上。

修改后的代码

import numpy as np
import matplotlib.pyplot as plt

fs = 1000
t = np.arange(0, 0.1, 1/fs)
N = len(t)
f_bin = fs / N
# 生成频率数组,也可以用np.fft.fftfreq(N, 1/fs)[:N//2]简化代码
f = np.arange(0, fs, f_bin)
# 截取前半部分频率并转换为kHz单位
f_khz = f[:N//2] / 1000

X = [np.fft.fft(np.sin(2 * np.pi * 100 * t)), 
     np.fft.fft(np.sin(2 * np.pi * 200 * t)), 
     np.fft.fft(np.sin(2 * np.pi * 300 * t))]
M = np.absolute(X)

fig, ax = plt.subplots()
# 方法1:用extent参数直接定义X轴的频率范围,自动生成刻度
im = ax.imshow(M[:,:N//2], cmap='viridis', aspect='auto', 
               extent=[f_khz[0], f_khz[-1], 0, len(M)-1])

# 方法2:手动控制刻度位置(如需固定显示关键频率点时用)
# ax.imshow(M[:,:N//2], cmap='viridis', aspect='auto')
# tick_indices = np.arange(0, N//2, N//10)  # 每隔N//10个索引设一个刻度
# ax.set_xticks(tick_indices)
# ax.set_xticklabels(np.round(f_khz[tick_indices], 2))  # 对应位置的kHz值

clb = fig.colorbar(im, ax=ax)
clb.ax.set_title("Magnitude")
ax.set_xlabel("Frequency (kHz)")
ax.set_ylabel("# FFT")
ax.set_title("Built-in FFT")
plt.show()

关键修改点说明

  • 频率数组匹配:截取f的前半部分(f[:N//2]),和你显示的M[:,:N//2]数据维度完全对齐,避免刻度错位。
  • extent参数用法:extent=[xmin, xmax, ymin, ymax]直接定义X轴的起止频率,matplotlib会自动生成合适的刻度,这是最便捷的实现方式。
  • 手动刻度自定义:如果需要固定显示特定频率点,可以用set_xticks指定索引位置,再用set_xticklabels对应上转换后的kHz值。

Stack Overflow常见相关方案补充

  • 多数场景会用np.fft.fftfreq(N, 1/fs)生成频率数组,它会自动处理正负频率,截取前半部分[:N//2]即可得到正频率轴,和你手动计算的f效果一致,代码更简洁。
  • 所有FFT可视化的核心要求都是频率轴长度与显示的FFT数据维度严格匹配,这是避免刻度混乱的关键。

内容的提问来源于stack exchange,提问作者ge45mue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:35:27