matplotlib 如何将多个声谱图子图合并成一个图?

1dkrff03  于 2023-01-26  发布在  其他
关注(0)|答案(2)|浏览(130)

我正在可视化四个类的声谱图,对于一个类,我的声谱图代码如下所示

把这当成一个画面。
产生这个的代码是

def spec(filename):
    time_period = 0.5 # FFT time period (in seconds). Can comfortably process time frames from 0.05 seconds - 10 seconds

    # ==============================================

    fs_rate, signal_original = wavfile.read(filename)
    total_time = int(np.floor(len(signal_original)/fs_rate))
    sample_range = np.arange(0,total_time,time_period)
    total_samples = len(sample_range)

    print ("Frequency sampling", fs_rate)
    print ("total time: ", total_time)
    print ("sample time period: ", time_period)
    print ("total samples: ", total_samples)

    output_array = []
    for i in sample_range:

#         print ("Processing: %d / %d (%d%%)" % (i/time_period + 1, total_samples, (i/time_period + 1)*100/total_samples))

        sample_start = int(i*fs_rate)
        sample_end = int((i+time_period)*fs_rate)
        signal = signal_original[sample_start:sample_end]

        l_audio = len(signal.shape)
        #print ("Channels", l_audio)

        if l_audio == 2:
            signal = signal.sum(axis=1) / 2
        N = signal.shape[0]
        #print ("Complete Samplings N", N)

        secs = N / float(fs_rate)
        # print ("secs", secs)
        Ts = 1.0/fs_rate # sampling interval in time
        #print ("Timestep between samples Ts", Ts)

        t = scipy.arange(0, secs, Ts) # time vector as scipy arange field / numpy.ndarray

        FFT = abs(scipy.fft(signal))
        FFT_side = FFT[range(int(N/2))] # one side FFT range
        freqs = scipy.fftpack.fftfreq(signal.size, t[1]-t[0])
        fft_freqs = np.array(freqs)
        freqs_side = freqs[range(int(N/2))] # one side frequency range
        fft_freqs_side = np.array(freqs_side)

        # Reduce to 0-5000 Hz
        bucket_size = 5
        buckets = 16

        FFT_side = FFT_side[0:bucket_size*buckets]
        fft_freqs_side = fft_freqs_side[0:bucket_size*buckets]

        # Combine frequencies into buckets
        FFT_side = np.array([int(sum(FFT_side[current: current+bucket_size])) for current in range(0, len(FFT_side), bucket_size)])
        fft_freqs_side = np.array([int(sum(fft_freqs_side[current: current+bucket_size])) for current in range(0, len(fft_freqs_side), bucket_size)])

        # FFT_side: Normalize (0-1)
        max_value = max(FFT_side)
        if (max_value != 0):
            FFT_side_norm = FFT_side / max_value

        # Append to output array
        output_array.append(FFT_side_norm)

    # ============================================

    # Plotting

    plt.figure(figsize=(4,7))

    plt.subplot(411)
    plt.subplots_adjust(hspace = 0.5)
    plt.plot(t, signal, "g") # plotting the signal
    plt.xlabel('Time')
    plt.ylabel('Amplitude')

    plt.subplot(412)
    diff = np.diff(fft_freqs_side)
    widths = np.hstack([diff, diff[-1]])
    plt.bar(fft_freqs_side, abs(FFT_side_norm), width=widths) # plotting the positive fft spectrum
    plt.xticks(fft_freqs_side, fft_freqs_side, rotation='vertical')
    plt.xlabel('Frequency (Hz)')
    plt.ylabel('Count single-sided')

    FFT_side_norm_line = FFT_side_norm.copy()
    FFT_side_norm_line.resize( (1,buckets) )

    plt.subplot(413)
    plt.imshow(FFT_side_norm_line)
    plt.xlabel('Image Representation 1D')
    plt.show()
    print("\n\n\n\n\n\n")

我怎样才能把四张像这样的图组合在一起,然后得到一张输出图呢?

dhxwm5r4

dhxwm5r41#

我建议使用matplotlib.pyplot.subplot_mosaic
上图是使用以下简单表达式获得的:

plt.subplot_mosaic('ab;ab;cd;cd;ef;..;gh;gh;ij;ij;kl')
hmae6n7t

hmae6n7t2#

您可以这样做:

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(x, y)
axs[0, 0].set_title('Axis [0, 0]')
axs[0, 1].plot(x, y, 'tab:orange')
axs[0, 1].set_title('Axis [0, 1]')
axs[1, 0].plot(x, -y, 'tab:green')
axs[1, 0].set_title('Axis [1, 0]')
axs[1, 1].plot(x, -y, 'tab:red')
axs[1, 1].set_title('Axis [1, 1]')

for ax in axs.flat:
    ax.set(xlabel='x-label', ylabel='y-label')

# Hide x labels and tick labels for top plots and y ticks for right plots.
for ax in axs.flat:
    ax.label_outer()

结果会是这样的:

相关问题