1

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,

1 Answer 1

3

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()
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, the code you posted works if I split the filter function into individual parts, I have not yet tried it within the loop structure originally posted. Is it possible to add labels to each of the lines and a legend using this method? Again I have tried unsuccessfully to get this to work.
I elaborated the example with legends. Maybe the unzip command (the asterix) confused you.
Great, Thank you again. It doesn't take much to confuse me, but to be honest I didn't notice the asterix. I will have to google this unzip command I think.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.