Plotting Multiple Plots on a single figure from within a for loop

Question:

I have reviewed the response to this question: How would I iterate over a list of files and plot them as subplots on a single figure?

But am none the wiser on how to achieve my goal. I would like to plot multiple data sets, with differing x axes, onto a single figure in Python. I have included a snippet of my code below, which performs an FFT on a dataset, then calculates 3 Butterworth filter outputs. Ideally I would like to have all plotted on a single figure, which I have attempted to achieve in the code below.
The for loop calculates the 3 Butterworth filter outputs, the code above – the FFT and the code directly below attempts to append the FFT curve and sqrt(0.5) line to the previously generated plots for display.

Any Direction or advice would be appreciated.

"""Performs a Fast Fourier Transform on the data specified at the base of the code"""
def FFT(col):
    x = io2.loc[1:,'Time']
    y = io2.loc[1:,col]
    # Number of samplepoints
    #N = 600
    N = pd.Series.count(x)
    N2 = int(N/2)
    # sample spacing
    #T = 1.0 / 800.0
    T = 1/(io2.loc[2,'Time'] - io2.loc[1,'Time'])
    #x = np.linspace(0.0, N*T, N)
    #y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
    yf = scipy.fftpack.fft(y)
    xf = np.linspace(0.0, 1.0/(2.0*T), N2)

fig=plt.figure()
plt.clf()
i=1
for order in [3, 6, 9]:
    ax=fig.add_subplot(111, label="order = %d" % order)
    b, a = butter_lowpass(cutoff, fs, order=order)
    w, h = freqz(b, a, worN=2000)

    ax.plot((fs * 0.5 / np.pi) * w, abs(h))
    i=i+1

ax4=fig.add_subplot(111, label='sqrt(0.5)', frame_on=False)
ax5=fig.add_subplot(111, label="FFT of "+col, frame_on=False)

ax4.plot([0, 0.5 * fs], [np.sqrt(0.5), np.sqrt(0.5)], '--')
ax5.plot(xf, 2.0/N * np.abs(yf[:N2]))
plt.xlabel('Frequency (Hz)')
plt.ylabel('Gain')
plt.grid(True)
plt.legend(loc='best')

#fig, ax = plt.subplots()
#ax.plot(xf, 2.0/N * np.abs(yf[:N2]), label="FFT of "+col)
plt.axis([0,5000,0,0.1])
#plt.xlabel('Frequency (Hz)')
#plt.ylabel('Amplitude (mm)')
#plt.legend(loc=0)
plt.show()

return

Kind Regards,

Asked By: chopboy

||

Answers:

Here you can find a minimal example of how to plot multiple lines with different x and y datasets. You are recreating the plot every time you type add_subplot(111). Instead, you should call plot multiple times. I have added an example for a single plot with multiple lines, as well as an example for one subplot per line.

import numpy as np
import matplotlib.pyplot as plt

x1 = np.arange(0, 10, 1)
x2 = np.arange(3, 12, 0.1)
x3 = np.arange(2, 8, 0.01)

y1 = np.sin(x1)
y2 = np.cos(x2**0.8)
y3 = np.sin(4.*x3)**3

data = []
data.append((x1, y1, 'label1'))
data.append((x2, y2, 'label2'))
data.append((x3, y3, 'label3'))

# All lines in one plot.
plt.figure()
for n in data:
    plt.plot(n[0], n[1], label=n[2])
plt.legend(loc=0, frameon=False)

# One subplot per data set.
cols = 2
rows = len(data)//2 + len(data)%2
plt.figure()
gs = plt.GridSpec(rows, cols)
for n in range(len(data)):
    i = n%2
    j = n//2
    plt.subplot(gs[j,i])
    plt.plot(data[n][0], data[n][1])
    plt.title(data[n][2])
plt.tight_layout()
plt.show()
Answered By: Chiel
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.