Skip to content

Spectrograms

ptfp.spectrograms

plot_spectrogram_from_timeseries

plot_spectrogram_from_timeseries(timeseries, q_value=None, q_min=None, q_max=None, f_min=20, f_max=None, start_time=None, end_time=None, time_resolution=None, frequency_resolution=None, whiten_timeseries=True, spectrogram_frequency_scale='log', colorbar_location='right', colormap='viridis', spectrogram_maximum_energy=25, fig_and_ax=None, plot_kws=None)

Produces a spectrogram given a gwpy TimeSeries, with some helpful manipulations. Descended with much modification from gwdetchar.scattering.plot._format_spectrogram.

Parameters

timeseries : gwpy.timeseries.TimeSeries
    The timeseries from which the spectrogram will be produced
q_value : Optional[float]
    A single value of q to fix for the Q transform which
    will generate the spectrogram.
    Exclusive with q_min and q_max
q_min : Optional[float]
    A minimum value for the range of q values which
    gwpy will optimize over when performing the q transform.
    Requires q_max and exclusive with q_value
q_max : Optional[float]
    A maximum value for the range of q values which
    gwpy will optimize over when performing the q transform.
    Requires q_min and exclusive with q_value
f_min : Optional[float]
    A minimum value for the frequency range of the spectrogram.
    Defaults to standard minimum frequency of 20 Hz.
f_max : Optional[float]
    A maximum value for the frequency range of the spectrogram.
    Defaults to Nyquist frequency.
start_time : Optional[float]
    The start time for the output segment of the spectrogram
end_time : Optional[float]
    The end time for the output segment of the spectrogram
time_resolution : Optional[float]
    The time resolution for the q_transform, passed directly
    to the tres argument of `TimeSeries.q_transform`
frequency_resolution : Optional[float]
    The frequency resolution for the q_transform, passed directly
    to the fres argument of `TimeSeries.q_transform`
whiten_timeseries : Optional[bool]
    Whether the data needs to be whitened.
    Defaults True, assuming unwhitened data.
    If data is whitened pass this as False.
spectrogram_frequency_scale : Optional[str]
    Options are "linear" and "log", defaults to "log"
colorbar_location : Optional[str]
    The location of the colorbar relative to the spectrogram.
    Options are 'top', 'bottom', 'left', 'right'.
    Defaults to 'right'.
colormap : Optional[str]
    The colormap to use, as matplotlib standard. Defaults to viridis.
spectrogram_maximum_energy : Optional[float]
    The value at which the spectrogram saturates, i.e. the top of the color bar.
    Defaults to 25.
fig_and_ax : Optional[Tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]]
    The figure and axis object onto which the spectrogram is plotted.
    If not passed, these will be generated
plot_kws : Optional[Dict]
    The dictionary of arguments for the Plot() call to make the figure and axes.

Returns

matplotlib.figure.Figure
    The figure object for the spectrogram
matplotlib.axes.Axes
    The axes on which the spectrogram is plotted
matplotlib.axes.Axes
    The axes on which the colorbar is plotted
matplotlib.colorbar.Colorbar
    The colorbar object
matplotlib.image.AxesImage
    The image of the spectrogram which was plotted`
Source code in ptfp/spectrograms.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
def plot_spectrogram_from_timeseries(
    timeseries: TimeSeries,
    q_value: Optional[float] = None,
    q_min: Optional[float] = None,
    q_max: Optional[float] = None,
    f_min: Optional[float] = 20,
    f_max: Optional[float] = None,
    start_time: Optional[float] = None,
    end_time: Optional[float] = None,
    time_resolution: Optional[float] = None,
    frequency_resolution: Optional[float] = None,
    whiten_timeseries: Optional[bool] = True,
    spectrogram_frequency_scale: Optional[str] = "log",
    colorbar_location: Optional[str] = "right",
    colormap: Optional[str] = "viridis",
    spectrogram_maximum_energy: Optional[float] = 25,
    fig_and_ax: Optional[Tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]] = None,
    plot_kws: Optional[Dict] = None,
) -> Tuple[
    matplotlib.figure.Figure,
    matplotlib.axes.Axes,
    matplotlib.axes.Axes,
    matplotlib.colorbar.Colorbar,
    matplotlib.image.AxesImage,
]:
    """Produces a spectrogram given a gwpy TimeSeries, with some helpful manipulations.
    Descended with much modification from gwdetchar.scattering.plot._format_spectrogram.

    Parameters
    ==========
        timeseries : gwpy.timeseries.TimeSeries
            The timeseries from which the spectrogram will be produced
        q_value : Optional[float]
            A single value of q to fix for the Q transform which
            will generate the spectrogram.
            Exclusive with q_min and q_max
        q_min : Optional[float]
            A minimum value for the range of q values which
            gwpy will optimize over when performing the q transform.
            Requires q_max and exclusive with q_value
        q_max : Optional[float]
            A maximum value for the range of q values which
            gwpy will optimize over when performing the q transform.
            Requires q_min and exclusive with q_value
        f_min : Optional[float]
            A minimum value for the frequency range of the spectrogram.
            Defaults to standard minimum frequency of 20 Hz.
        f_max : Optional[float]
            A maximum value for the frequency range of the spectrogram.
            Defaults to Nyquist frequency.
        start_time : Optional[float]
            The start time for the output segment of the spectrogram
        end_time : Optional[float]
            The end time for the output segment of the spectrogram
        time_resolution : Optional[float]
            The time resolution for the q_transform, passed directly
            to the tres argument of `TimeSeries.q_transform`
        frequency_resolution : Optional[float]
            The frequency resolution for the q_transform, passed directly
            to the fres argument of `TimeSeries.q_transform`
        whiten_timeseries : Optional[bool]
            Whether the data needs to be whitened.
            Defaults True, assuming unwhitened data.
            If data is whitened pass this as False.
        spectrogram_frequency_scale : Optional[str]
            Options are "linear" and "log", defaults to "log"
        colorbar_location : Optional[str]
            The location of the colorbar relative to the spectrogram.
            Options are 'top', 'bottom', 'left', 'right'.
            Defaults to 'right'.
        colormap : Optional[str]
            The colormap to use, as matplotlib standard. Defaults to viridis.
        spectrogram_maximum_energy : Optional[float]
            The value at which the spectrogram saturates, i.e. the top of the color bar.
            Defaults to 25.
        fig_and_ax : Optional[Tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]]
            The figure and axis object onto which the spectrogram is plotted.
            If not passed, these will be generated
        plot_kws : Optional[Dict]
            The dictionary of arguments for the Plot() call to make the figure and axes.

    Returns
    =======
        matplotlib.figure.Figure
            The figure object for the spectrogram
        matplotlib.axes.Axes
            The axes on which the spectrogram is plotted
        matplotlib.axes.Axes
            The axes on which the colorbar is plotted
        matplotlib.colorbar.Colorbar
            The colorbar object
        matplotlib.image.AxesImage
            The image of the spectrogram which was plotted`
    """
    # Infer the appropriate frequency range
    # Default to nyquist frequency as f_max
    f_max = 1 / 2 / timeseries.dt.value if f_max is None else f_max
    frequency_range = (f_min, f_max)

    # Infer the appropriate outseg
    # These settings will likely be a bit nasty if used, since
    # They will show the whole data segment
    start_time = timeseries.t0.value if start_time is None else start_time
    end_time = (
        timeseries.t0.value + timeseries.duration.value
        if end_time is None
        else end_time
    )
    outseg = (start_time, end_time)

    # Infer the q range based on inputs
    if q_value is not None and q_min is None and q_max is None:
        # If only q_value is set use that to fix the range
        q_range = (q_value, q_value)
    elif q_value is not None:
        # q_value is set and max or min is set, this is overspecified
        raise ValueError(
            "q range is overspecified, " "either fix a value or give a max and min"
        )
    elif q_min is not None and q_max is not None:
        # Set the range as requested
        q_range = (q_min, q_max)
    else:
        # Insufficient information
        raise ValueError(
            "q range is underspecified, " "either fix a value or give a max and min"
        )

    # Compute the q transform of the data
    qspecgram = timeseries.q_transform(
        qrange=q_range,
        frange=frequency_range,
        outseg=outseg,
        fres=frequency_resolution,
        tres=time_resolution,
        whiten=whiten_timeseries,
    )

    if fig_and_ax is None:
        plot_kws = {} if plot_kws is None else plot_kws
        fig = Plot(**plot_kws)
        ax = fig.add_subplot(111)
    else:
        fig, ax = fig_and_ax

    # Some tricks to plot the spectrogram and make the colorbar
    # While giving us control over its axes location
    divider = make_axes_locatable(ax)
    cax = divider.append_axes(colorbar_location, size="5%", pad=0.05)
    im = ax.imshow(
        qspecgram,
        vmin=0,
        vmax=spectrogram_maximum_energy,
        cmap=colormap,
        norm="linear",
    )
    orientation = (
        "horizontal"
        if colorbar_location == "top" or colorbar_location == "bottom"
        else "vertical"
    )
    cb = fig.colorbar(im, cax=cax, orientation=orientation, label="Normalized Energy")
    if orientation == "horizontal":
        cax.tick_params(top=True, labeltop=True, bottom=False, labelbottom=False)
        cax.xaxis.set_label_position("top")

    # Set scale and some universal labels
    ax.set_yscale(spectrogram_frequency_scale)
    ax.set_ylabel("Frequency [Hz]")
    ax.set_xlabel("Time [s]")

    return fig, ax, cax, cb, im