代码之家  ›  专栏  ›  技术社区  ›  ymmx

在另一个具有sahex属性的轴上进行缩放时,是否更新多个matplotlib轴?

  •  0
  • ymmx  · 技术社区  · 6 年前

    我想画四条曲线,左边两条时间曲线,右边两条基于时间曲线的FFT。 例如:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy import signal
    
    
    Fs=1024
    t=np.arange(0,10,1/Fs)
    F=np.arange(0,10,1/Fs)
    x = np.sin(2 * 3.1416 * F *t )
    
    plt.figure()
    ax1 = plt.subplot(221)
    plt.plot(t,x)
    ax2 = plt.subplot(222)
    f, Pxx_den = signal.periodogram(x, Fs)
    line1, = plt.plot(f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]] )
    
    ax3 = plt.subplot(223, sharex=ax1)
    plt.plot(t,x)
    ax4 = plt.subplot(224)
    f, Pxx_den = signal.periodogram(x, Fs)
    line1, = plt.plot(f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]] )
    
    
    def on_xlims_change1(axes):
        lim = axes.get_xlim()
        f, Pxx_den = signal.periodogram(x[np.bitwise_and(t >lim[0] , t <lim[1])], Fs)
        ax2.clear()
        ax2.plot(f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]] )
    
    def on_xlims_change2(axes):
        lim = axes.get_xlim()
        f, Pxx_den = signal.periodogram(x[np.bitwise_and(t >lim[0] , t <lim[1])], Fs)
        ax4.clear()
        ax4.plot(f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]] )
    
    ax1.callbacks.connect('xlim_changed', on_xlims_change1)
    ax3.callbacks.connect('xlim_changed', on_xlims_change2)
    
    
    plt.show()
    

    我所寻求的是更新 ax2 ax4 x axis ax1 ax3 已修改。每次 X轴 属于 ax1 ax3 修改后,我只想在显示的曲线范围内计算FFT。 所以我几乎完成了这个部分。然而,因为 ax1 ax3 共享x轴。我原以为两个FFT图应该更新,但他们没有更新。

    enter image description here

    因此,当我放大一个时间轴时,只有直接到右侧的FFT被更新,而不是全部更新。 我不知道哪里丢了什么?

    1 回复  |  直到 4 年前
        1
  •  2
  •   ImportanceOfBeingErnest    6 年前

    仅当限制在外部实际更改的轴触发回调。您可以只使用一个函数同时更新两个绘图。

    def onlimschange(ax):
        on_xlims_change1(ax)
        on_xlims_change2(ax)
    
    def on_xlims_change1(axes):
        lim = axes.get_xlim()
        f, Pxx_den = signal.periodogram(x[np.bitwise_and(t >lim[0] , t <lim[1])], Fs)
        ax2.clear()
        ax2.plot(f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]] )
    
    def on_xlims_change2(axes):
        lim = axes.get_xlim()
        f, Pxx_den = signal.periodogram(x[np.bitwise_and(t >lim[0] , t <lim[1])], Fs)
        ax4.clear()
        ax4.plot(f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]] )
    
    ax1.callbacks.connect('xlim_changed', onlimschange)
    ax3.callbacks.connect('xlim_changed', onlimschange)
    

    可以共享任意轴的一般解决方案是从 source_axes 到a target_axes 并循环所有共享轴,以根据映射更新相应的目标轴。

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy import signal
    
    Fs=1024.
    t=np.arange(0,10,1/Fs)
    F=np.arange(0,10,1/Fs)
    x = np.sin(2 * 3.1416 * F *t )
    
    plt.figure()
    ax1 = plt.subplot(221)
    plt.plot(t,x)
    ax2 = plt.subplot(222)
    f, Pxx_den = signal.periodogram(x, Fs)
    line1, = plt.plot(f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]] )
    
    ax3 = plt.subplot(223, sharex=ax1)
    plt.plot(t,x)
    ax4 = plt.subplot(224)
    f, Pxx_den = signal.periodogram(x, Fs)
    line1, = plt.plot(f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]] )
    
    def func1(source_axes):
        lim = source_axes.get_xlim()
        f, Pxx_den = signal.periodogram(x[np.bitwise_and(t >lim[0] , t <lim[1])], Fs)
        X,Y = f[:np.where(f>50)[0][0]],Pxx_den[:np.where(f>50)[0][0]]
        return X,Y
    
    mapping = {ax1 : [ax2, func1], ax3 : [ax4, func1]}
    
    def onlimschange(source_axes):
        for source_ax in source_axes.get_shared_x_axes().get_siblings(source_axes):
            target_ax = mapping[source_ax][0]
            X,Y = mapping[source_ax][1](source_axes)
            target_ax.clear()
            target_ax.plot(X,Y)
    
    ax1.callbacks.connect('xlim_changed', onlimschange)
    ax3.callbacks.connect('xlim_changed', onlimschange)
    
    
    plt.show()