如何在Matplotlib中实现缩放某轴时联动更新多轴(含时域FFT示例)
实现Matplotlib时域与FFT图的联动缩放
我来帮你搞定这个需求——让左侧共享x轴的时域图和右侧对应的FFT图实现联动缩放,当你拖动或缩放任意左侧时域轴时,所有相关的图都会同步更新。
完整实现代码
import matplotlib.pyplot as plt import numpy as np from scipy import signal # 初始化参数 Fs = 1024 # 采样率 t = np.arange(0, 10, 1/Fs) # 时间轴 freq = 5 # 信号频率,固定频率方便演示 x = np.sin(2 * np.pi * freq * t) # 生成基础正弦信号 # 创建画布和子图 fig = plt.figure(figsize=(12, 8)) ax1 = plt.subplot(221) ax1.plot(t, x) ax1.set_title('时域曲线1') ax1.set_xlabel('时间(s)') ax2 = plt.subplot(222) # 初始计算全时域的功率谱 f_full, Pxx_den_full = signal.periodogram(x, Fs) # 只显示0-50Hz的频谱 freq_cut = np.where(f_full > 50)[0][0] line2, = ax2.plot(f_full[:freq_cut], Pxx_den_full[:freq_cut]) ax2.set_title('FFT频谱1') ax2.set_xlabel('频率(Hz)') ax3 = plt.subplot(223, sharex=ax1) ax3.plot(t, x + np.random.randn(len(t))*0.1) # 加噪声区分两条时域曲线 ax3.set_title('时域曲线2(共享x轴)') ax3.set_xlabel('时间(s)') ax4 = plt.subplot(224) line4, = ax4.plot(f_full[:freq_cut], Pxx_den_full[:freq_cut]) ax4.set_title('FFT频谱2') ax4.set_xlabel('频率(Hz)') # 定义联动更新函数 def update_fft(axes): # 获取当前时域轴的x范围 t_start, t_end = axes.get_xlim() # 截取对应时间区间的信号数据 mask = np.bitwise_and(t >= t_start, t <= t_end) x_segment = x[mask] if axes == ax1 else (x + np.random.randn(len(t))*0.1)[mask] # 重新计算该区间的功率谱 f, Pxx_den = signal.periodogram(x_segment, Fs) # 同样只显示0-50Hz freq_cut_new = np.where(f > 50)[0][0] if len(np.where(f > 50)[0])>0 else len(f) # 更新对应的FFT曲线 if axes == ax1: line2.set_data(f[:freq_cut_new], Pxx_den[:freq_cut_new]) ax2.relim() ax2.autoscale_view() else: line4.set_data(f[:freq_cut_new], Pxx_den[:freq_cut_new]) ax4.relim() ax4.autoscale_view() # 刷新画布 fig.canvas.draw_idle() # 给两个时域轴绑定x轴范围变化事件 ax1.callbacks.connect('xlim_changed', update_fft) ax3.callbacks.connect('xlim_changed', update_fft) plt.tight_layout() plt.show()
关键细节说明
- 共享x轴基础:通过
sharex=ax1让ax3和ax1自动同步x轴缩放,但FFT图需要额外的事件监听来更新数据 - 事件回调机制:使用
callbacks.connect('xlim_changed', update_fft)监听时域轴的x范围变化,一旦触发就执行更新逻辑 - 动态频谱计算:每次缩放后,截取当前时间区间的信号段,重新计算该段的功率谱,再更新FFT曲线的数据源
- 自动适配显示:调用
relim()和autoscale_view()让FFT轴自动调整y轴范围,确保新的频谱能完整显示
现在运行这段代码,你缩放任意左侧的时域图,对应的右侧FFT图就会自动更新为当前选中时间区间的频谱啦!
内容的提问来源于stack exchange,提问作者ymmx
相关产品推荐
相关产品推荐

