pyriodic package#
Submodules#
pyriodic.circular#
- class pyriodic.circular.Circular(data: ndarray, labels: list | ndarray | None = None, unit: str = 'radians', full_range: int | None = None)#
Bases:
object
A class for representing and working with circular data (e.g., angles, time-of-day, phase).
This class supports circular statistics and visualization of data that wraps around a fixed range, such as angles (in radians or degrees), phases, hours, or other cyclic measurements. It provides basic unit validation, conversion between degrees and radians, and visualisation tools.
- Parameters:
data (array-like) – A sequence of numerical values representing circular measurements. Values should be in the range appropriate to the specified unit.
labels (array-like of str or int, optional) – Optional condition labels or identifiers corresponding to each data point.
unit (str, optional) – The unit of the input data. Must be one of {“radians”, “degrees”}. Default is “radians”. Assumes radian range to be from 0 to 2pi.
full_range (int, optional)
- data#
The circular data as a NumPy array.
- Type:
ndarray
- labels#
Optional labels (e.g., condition tags) for each data point.
- Type:
ndarray or list
- unit#
Unit of measurement, either “radians” or “degrees”.
- Type:
str
- classmethod from_multiple(circular_objects, labels=None)#
- mean(group_by_label: bool = False)#
- plot(ax=None, histogram=False, group_by_labels=False)#
- r()#
pyriodic.desc#
- pyriodic.desc.angular_deviation(rad: ndarray)#
- pyriodic.desc.circular_mean(rad: ndarray, wrap_to_2pi: bool = True)#
Compute the mean angle from a list of angles in radians.
Parameters:#
- radnp.ndarray
Array of angles in radians.
- wrap_to_2pibool, default=True
If True, wraps result to range [0, 2π]. If False, result is in [-π, π].
Returns:#
- meanfloat
The circular mean angle.
- pyriodic.desc.circular_r(rad: ndarray)#
Compute the length of the mean resultant vector ( r ), a measure of circular concentration.
\[r = \sqrt{\bar{C}^2 + \bar{S}^2}\]
- pyriodic.desc.circular_standard_deviation(rad: ndarray)#
pyriodic.phase_events#
- class pyriodic.phase_events.PhaseEvents(phase_dict: dict)#
Bases:
object
- mean()#
- plot(histogram: ndarray | None = None, savepath: Path | str | None = None)#
- r()#
- to_circular(include: str | list[str])#
- pyriodic.phase_events.compute_segment_outliers(segments, threshold=3, sampling_rate=None)#
Identify segment durations that deviate > threshold * SD from the mean. Optionally normalize by sampling_rate.
- pyriodic.phase_events.create_phase_events(phase_ts: ndarray, events: ndarray, event_labels: ndarray | None = None, unit: str = 'radians', first_samp: int = 0, rejection_method: str | None = None, rejection_criterion: float | None = None, return_rejected: bool = False) PhaseEvents | tuple[PhaseEvents, list[int]] #
Create Circular object(s) from a phase angle time series and event markers. Optionally apply cycle-based rejection criteria to exclude events occurring during atypical phase dynamics.
- Parameters:
phase_ts (np.ndarray) – 1D array of phase values (in radians), typically spanning multiple 0–2π cycles.
events (np.ndarray) – 1D array of sample indices at which to extract phase values.
event_labels (np.ndarray, optional) – Labels for grouping events. If None, returns a single Circular object; otherwise, returns a PhaseEvents container grouped by unique labels.
unit (str) – Unit of the input phase time series and the desired unit for output Circular objects. Must be either ‘radians’ or ‘degrees’. Internally, all computations are performed in radians.
first_samp (int) – Offset to subtract from each event index to align with the phase time series (useful if phase_ts is a segment of a longer recording).
rejection_method (str, optional) –
Method to reject events based on surrounding phase dynamics. Currently supported:
’segment_duration_sd’ : excludes events occurring during rising or falling phase segments whose durations deviate more than rejection_criterion standard deviations from the mean across cycles.
rejection_criterion (float, optional) – Threshold (in standard deviation units) for identifying outlier segments. Only used if rejection_method=’segment_duration_sd’. Default is 3.
return_rejected (bool) – If True, also return a list of rejected event indices.
- Returns:
Circular or PhaseEvents – If event_labels is None, returns a single Circular object. Otherwise, returns a PhaseEvents object containing condition-grouped Circular data.
(optional) list[int] – If return_rejected is True, returns a second value: the list of event indices that were rejected.
- pyriodic.phase_events.get_outlier_sample_indices(segments, outlier_indices)#
Convert outlier segments to a flat set of sample indices for fast lookup.
- pyriodic.phase_events.get_phase_segments(phase_ts: ndarray)#
Identify rising (0→π) and falling (π→2π) phase segments in a wrapped phase signal.
- Parameters:
phase_ts (np.ndarray) – 1D array of phase values (in radians), assumed to evolve continuously over time.
- Returns:
rising_segments (list of (start_idx, stop_idx)) – List of index tuples for rising phase segments (0 to π).
falling_segments (list of (start_idx, stop_idx)) – List of index tuples for falling phase segments (π to 2π).
pyriodic.preproc module#
- class pyriodic.preproc.RawSignal(data, fs, info=None)#
Bases:
object
- copy()#
- filter_bandpass(low, high)#
- property history#
- interpolate_missing()#
- phase_hilbert()#
Extract instantaneous phase angle using the Hilbert Transform.
- Parameters:
ts (np.ndarray) – 1D time series
- Returns:
phase angles in radians (0 to 2π)
- Return type:
np.ndarray
- phase_linear(peak_finder=None, distance=100, prominence=0.01)#
Extract phase using linear interpolation between peaks and troughs at
- Parameters:
peak_finder (callable) – Optional custom function(ts, **kwargs) -> np.ndarray of peak indices.
distance (int) – Minimum distance between peaks.
prominence (float) – Prominence threshold for peak detection.
- Returns:
phase peaks troughs
- phase_onepoint(peak_finder=None, distance=100, prominence=0.01)#
Extract phase using linear interpolation between from 0 to 2pi between peaks.
- Parameters:
peak_finder (callable) – Optional custom function(ts, **kwargs) -> np.ndarray of peak indices.
distance (int) – Minimum distance between peaks.
prominence (float) – Prominence threshold for peak detection.
- Returns:
phase peaks
- phase_threepoint(peak_finder: Callable[[...], ndarray] | None = None, distance: int = 100, prominence: float | int = 0.01, percentile: float | int = 50, descent_window: int = 5)#
Extract phase using a three-point method: Peak → descending slope → flat region → ascending slope → next peak.
- Parameters:
peak_finder (callable) – Optional function(ts, **kwargs) → np.ndarray of peak indices.
distance (int) – Min distance between peaks (used if no custom peak_finder).
prominence (float) – Prominence threshold for peak detection.
percentile (float) – Percentile of absolute gradient below which region is considered ‘flat’.
descent_window (int) – Number of samples used to confirm descent/ascent before/after flat region.
- Returns:
Phase array in radians (0 to 2π) peaks (np.ndarray): Indices of detected peaks troughs (list of tuples): List of (trough_start, trough_end) for flat segments
- Return type:
phase (np.ndarray)
- remove_outliers(threshold=2.5, linear_interpolation=True)#
Removes outliers …. threshold + linear interpolation
- zscore()#
Normalises the signal in-place to mean 0 and unit variance.
pyriodic.stats module#
- pyriodic.stats.angular_randomisation_test(a: Circular, b: Circular)#
This function performs the angular randomisation test for homogeneity of 2 groups
https://ijnaa.semnan.ac.ir/article_5992_e5a258374dedcbb40d792b81bfc94591.pdf
H0: the samples come from the same population HA: the samples do not come from the same population
- pyriodic.stats.kuiper_test(a: Circular)#
Perform Kuiper’s test for uniformity on circular data.
- Parameters:
a (Circular) – An instance of the Circular class containing the data to test.
return_stat (bool) – If True, return the test statistic in addition to the p-value.
- Returns:
p_value (float) – The p-value for the test.
stat (float) – The Kuiper test statistic.
pyriodic.utils module#
- pyriodic.utils.dat2rad(data: ndarray | float | int, full_range: float | int = 360)#
- pyriodic.utils.rad2dat(rad: ndarray | float | int, full_range: float | int = 360)#
pyriodic.viz#
- class pyriodic.viz.CircPlot(circ: Circular, group_by_labels: bool = True, colours=None, fig_size=(6, 6), dpi=300, ax=None, ylim=None)#
Bases:
object
- add_circular_mean(grouped: bool | None = None, **kwargs)#
Plot mean resultant vector(s) as arrows.
- Parameters:
grouped (bool, optional) – If None, uses self.group_by_labels. If True, plots a vector per label. If False, plots a single mean vector for all data.
kwargs (dict) – Additional keyword arguments passed to ax.arrow. Common kwargs: width, color, alpha, linewidth.
- add_density(kappa=20, n_bins=500, grouped: bool | None = None, **kwargs)#
Add a circular density estimate using Von Mises KDE.
- Parameters:
kappa (float) – Concentration parameter of the Von Mises distribution (higher = sharper).
n_bins (int) – Number of angular bins to evaluate the density on.
grouped (bool, optional) – If None, uses self.group_by_labels. If True, plots a density curve for each label separately. If False, plots a single joint density curve for all data.
kwargs (dict) – Additional keyword arguments passed to ax.plot (e.g., linewidth, linestyle, alpha).
- add_histogram(data: dict[str, ndarray] | ndarray | None = None, bins=36, alpha=0.2, color: str = 'grey')#
Plot histogram as radial bars on the polar axis. If data is None, uses circular data in self.circs.
Parameters: - data: Optional dict[label] = array or a single array. - bins: Number of angular bins (default 36). - alpha: Transparency of bars.
- add_legend(location='upper right', **kwargs)#
Add a legend to the plot.
- Parameters:
location (str) – Position of the legend (default is ‘upper right’).
kwargs (dict) – Additional arguments passed to ax.legend().
- add_points(grouped: bool | None = None, **kwargs)#
Plot circular data points on the polar axis.
- Parameters:
grouped (bool, optional) – If None, uses the self.group_by_labels setting. If True, plots each label separately. If False, plots all data points together, ignoring labels.
kwargs (dict) – Additional keyword arguments passed to ax.scatter, such as s, alpha, or marker.
- prepare_ax(ylim)#
- save(filename, **kwargs)#
Save the figure to a file
- show()#
- pyriodic.viz.plot_phase_diagnostics(phase_angles: dict[str, ndarray], fs: int | float, data: ndarray | None = None, events: list | ndarray | None = None, event_labels: list | ndarray | None = None, peaks=None, troughs=None, flat_start_stop=None, savepath=None, figsize=None, interactive: bool = False, window_duration: float = 20.0)#
- Parameters:
phase_angles (dict[str, np.ndarray]) – Dictionary of named phase angle signals (e.g., {“3-point”: …, “Hilbert”: …}). Each should be 1D array of same length as data.
fs (float) – Sampling frequency (Hz).
data (np.ndarray, optional) – Raw or preprocessed time series signal (same length as phase arrays).
events (list[int] or np.ndarray, optional) – Sample indices of events to mark (e.g., stimulus or response times).
event_labels (list[str], optional) – Label for each event (same length as events). Used for color grouping.
peaks (list[int] or np.ndarray, optional) – Sample indices of identified peaks.
troughs (list[int] or np.ndarray, optional) – Sample indices of identified troughs.
flat_start_stop (list[tuple[int, int]] or list[int], optional) – Flat segments as start–stop index tuples or flat indices directly.
savepath (str or Path, optional) – If provided, saves static plot to this location (only applies if interactive=False).
figsize (tuple[int, int], optional) – Size of the figure in inches (only applies if interactive=False).
interactive (bool) – If True, launches an interactive slider-based window viewer (Matplotlib).
window_duration (float) – Duration (in seconds) of each visible window in interactive mode.
- Returns:
fig (matplotlib.figure.Figure) – The created figure.
axes (list[matplotlib.axes.Axes]) – The axes used in the plot (one per row: signal + phase tracks).
- pyriodic.viz.vonmises_kde(data, kappa, min_x=0, max_x=6.283185307179586, n_bins=100)#