Source code for neurokit2.signal.signal_rate

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np

from .signal_period import signal_period


[docs] def signal_rate( peaks, sampling_rate=1000, desired_length=None, interpolation_method="monotone_cubic", show=False, ): """**Compute Signal Rate** Calculate signal rate (per minute) from a series of peaks. It is a general function that works for any series of peaks (i.e., not specific to a particular type of signal). It is computed as ``60 / period``, where the period is the time between the peaks (see func:`.signal_period`). .. note:: This function is implemented under :func:`.signal_rate`, but it also re-exported under different names, such as :func:`.ecg_rate`, or :func:`.rsp_rate`. The aliases are provided for consistency. Parameters ---------- peaks : Union[list, np.array, pd.DataFrame, pd.Series, dict] The samples at which the peaks occur. If an array is passed in, it is assumed that it was obtained with :func:`.signal_findpeaks`. If a DataFrame is passed in, it is assumed it is of the same length as the input signal in which occurrences of R-peaks are marked as "1", with such containers obtained with e.g., :func:.`ecg_findpeaks` or :func:`.rsp_findpeaks`. sampling_rate : int The sampling frequency of the signal that contains peaks (in Hz, i.e., samples/second). Defaults to 1000. desired_length : int If left at the default None, the returned rated will have the same number of elements as ``peaks``. If set to a value larger than the sample at which the last peak occurs in the signal (i.e., ``peaks[-1]``), the returned rate will be interpolated between peaks over ``desired_length`` samples. To interpolate the rate over the entire duration of the signal, set ``desired_length`` to the number of samples in the signal. Cannot be smaller than or equal to the sample at which the last peak occurs in the signal. Defaults to ``None``. interpolation_method : str Method used to interpolate the rate between peaks. See :func:`.signal_interpolate`. ``"monotone_cubic"`` is chosen as the default interpolation method since it ensures monotone interpolation between data points (i.e., it prevents physiologically implausible "overshoots" or "undershoots" in the y-direction). In contrast, the widely used cubic spline interpolation does not ensure monotonicity. show : bool If ``True``, shows a plot. Defaults to ``False``. Returns ------- array A vector containing the rate (peaks per minute). See Also -------- signal_period, signal_findpeaks, signal_fixpeaks, signal_plot Examples -------- .. ipython:: python import neurokit2 as nk # Create signal of varying frequency freq = nk.signal_simulate(1, frequency = 1) signal = np.sin((freq).cumsum() * 0.5) # Find peaks info = nk.signal_findpeaks(signal) # Compute rate using 2 methods rate1 = nk.signal_rate(peaks=info["Peaks"], desired_length=len(signal), interpolation_method="nearest") rate2 = nk.signal_rate(peaks=info["Peaks"], desired_length=len(signal), interpolation_method="monotone_cubic") # Visualize signal and rate on the same scale @savefig p_signal_rate1.png scale=100% nk.signal_plot([signal, rate1, rate2], labels = ["Original signal", "Rate (nearest)", "Rate (monotone cubic)"], standardize = True) @suppress plt.close() """ period = signal_period(peaks, sampling_rate, desired_length, interpolation_method) rate = 60 / period if show is True: _signal_rate_plot(rate, peaks, sampling_rate, interpolation_method) return rate
# ============================================================================= # Internals # ============================================================================= def _signal_rate_plot( rate, peaks, sampling_rate=None, interpolation_method=None, title="Rate", ytitle="Cycle per minute", color="black", color_mean="orange", color_points="red", ax=None, ): # Prepare plot if ax is None: fig, ax = plt.subplots() if sampling_rate is None: x_axis = np.arange(0, len(rate)) ax.set_xlabel("Time (samples)") else: x_axis = np.linspace(0, len(rate) / sampling_rate, len(rate)) ax.set_xlabel("Time (seconds)") if interpolation_method is not None: title += " (interpolation method: " + str(interpolation_method) + ")" ax.set_title(title) ax.set_ylabel(ytitle) # Plot continuous rate ax.plot( x_axis, rate, color=color, label="Rate", linewidth=1.5, ) # Plot points if peaks is not None: ax.scatter( x_axis[peaks], rate[peaks], color=color_points, ) # Show average rate rate_mean = rate.mean() ax.axhline(y=rate_mean, label="Mean", linestyle="--", color=color_mean) ax.legend(loc="upper right") return ax