0

I am using the Lombscargle function to output the power spectrum for a signal I pass as input, I am able to get the plots one after another but the task at hand is to plot these graphs using subplots in a way that there are 5 rows, 4 cols.

An example for signal would be:

signal = [ '254.24', '254.32', '254.4', '254.84', '254.24', '254.28', '254.84', '253.56', '253.76', '253.32', '253.88', '253.72', '253.92', '251.56', '253.04', '244.72', '243.84', '246.08', '245.84', '249.0', '250.08', '248.2', '253.12', '253.2', '253.48', '253.88', '253.12', '253.4', '253.4']

from scipy.signal import lombscargle 

def LSP_scipy(signal):
    start_ang_freq = 2 * np.pi * (60/60)
    end_ang_freq = 2 * np.pi * (240/60)
    SAMPLES = 5000
    SAMPLE_SPACING = 1/15 

    t = np.linspace(0,len(signal)*SAMPLE_SPACING,len(signal))
    period_freq = np.linspace(start_ang_freq,end_ang_freq,SAMPLES)
    
    modified_signal_axis = []
    modified_time_axis = []
    for count,value in enumerate(signal):
        if value != 'None':
            modified_signal_axis.append(float(value))
            modified_time_axis.append(t[count])
        prog = lombscargle(modified_time_axis, modified_signal_axis, period_freq, normalize=False, precenter = True)
    fig, axes = plt.subplots()
    ax.plot(period_freq,prog)

How do I plot these graphs in a matrix format? This is what I am getting after executing this code.

Trying loop approach, Result is this

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158

3 Answers3

1

You can use for loop and iterate over subplots. A very simple example is shown below.The subplots method creates the figure along with the subplots and store in the ax array.

import matplotlib.pyplot as plt

x = np.linspace(0, 10)
y = range(10)


fig, ax = plt.subplots(nrows=2, ncols=2)

for row in ax:
   for col in row:
      col.plot(x, y)


plt.show()

# or you can also do

for in range(2):         # row=0, col=0
  for j in range(2):     # row=0, col=1
     ax[i, j].plot(x,y)  # row=1, col=0
                         # row=1, col=1
Priya
  • 723
  • 1
  • 5
  • 7
  • Hey I did try this approach, but I am not getting the desired results. Refer the last image, after trying your soln, I have 20 entries, and want all of them in 1 matrix. – AMANDEEP KAUR Sep 17 '21 at 18:18
  • what is signal here? – Priya Sep 17 '21 at 18:26
  • For each plot there should be one pair of x-values and y-values(x, y), I don't understand how you got multiple plots in the first place with the line `ax.plot(period_freq,prog)` in your code(cause it generates a single plot). Post a reproducible example. – Priya Sep 17 '21 at 18:38
  • Like the example of signal I gave, I have 20 such more rows, which are fed sequentially to the code stated above, I want each rows result forms as 1 grid element In the 5x4 matrix. – AMANDEEP KAUR Sep 17 '21 at 18:41
  • Thanks! I used this approach and was able to solve the problem. – AMANDEEP KAUR Sep 18 '21 at 03:51
  • glad it helped! – Priya Sep 19 '21 at 04:19
1

Then one idea is to take the signals into an array of shape=(20,1), where each row corresponds to signal amplitude or some other measurable quantity. Then you could do as below (check the output keeping only the lines till plt.text you will get the idea).

 for i in range(1, 21):
    plt.subplot(5, 4, i)
    plt.text(0.5, 0.5, str((5, 4, i)),
         fontsize=18, ha='center')
    # Call the function here...get the value of period_freq and prog
    period_freq,prog = LSP_scipy(signal[i])
    plt.plot(period_freq, prog) 
Priya
  • 723
  • 1
  • 5
  • 7
1
  • See inline comments to add and flatten the subplots.
  • This is an implementation of flattening the axes array from this answer of the duplicate.
from scipy.signal import lombscargle
from matplotlib.ticker import FormatStrFormatter
import numpy as np
import matplotlib.pyplot as plt

def LSP_scipy(signal):
    start_ang_freq = 2 * np.pi * (60/60)
    end_ang_freq = 2 * np.pi * (240/60)
    SAMPLES = 5000
    SAMPLE_SPACING = 1/15 

    t = np.linspace(0, len(signal)*SAMPLE_SPACING, len(signal))
    period_freq = np.linspace(start_ang_freq, end_ang_freq, SAMPLES)
    
    modified_signal_axis = []
    modified_time_axis = []
    
    # create the figure and subplots
    fig, axes = plt.subplots(5, 6, figsize=(20, 9), sharex=False, sharey=False)
    
    # flatten the array
    axes = axes.ravel()
    
    for count, value in enumerate(signal):
        if value != 'None':
            modified_signal_axis.append(float(value))
            modified_time_axis.append(t[count])
        prog = lombscargle(modified_time_axis, modified_signal_axis, period_freq, normalize=False, precenter=True)
        
        # plot
        axes[count].plot(period_freq, prog)
        
        # format the axes
        axes[count].set(title=value)
        # some plot have an exponential offset on the yaxis, this turns it off
        axes[count].ticklabel_format(useOffset=False)
        # some yaxis values are long floats, this formats them to 3 decimal places
        axes[count].yaxis.set_major_formatter(FormatStrFormatter('%.3f'))
        
    # format the figure
    fig.tight_layout()


signal = [ '254.24', '254.32', '254.4', '254.84', '254.24', '254.28', '254.84', '253.56', '253.76', '253.32', '253.88', '253.72', '253.92', '251.56', '253.04', '244.72', '243.84', '246.08', '245.84', '249.0', '250.08', '248.2', '253.12', '253.2', '253.48', '253.88', '253.12', '253.4', '253.4']
LSP_scipy(signal[:20])  # as per comment, only first 20

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
  • 1
    Thanks, Trenton! This is exactly what I needed! – AMANDEEP KAUR Sep 19 '21 at 18:08
  • 1
    @AMANDEEPKAUR You're welcome, I'm glad this works for you. Since it's essentially the same implementation as the duplicate answer I closed the question to, I posted this answer as a community wiki. I don't accumulate rep for this answer, so feel free to upvote the linked answer, if you're inclined. Best Regards. – Trenton McKinney Sep 19 '21 at 18:48