Pairwise Comparisons
The pairwise module provides data structures for unit-by-unit comparison
matrices. PairwiseCompMatrix holds a single (N, N) matrix (e.g.,
correlation or distance between all pairs of units), while
PairwiseCompMatrixStack holds an (N, N, S) stack of such matrices
across multiple conditions or time windows.
PairwiseCompMatrix
- class spikelab.spikedata.pairwise.PairwiseCompMatrix(matrix, labels=None, metadata=<factory>)[source]
Bases:
objectA data class for n x n pairwise comparison matrices (e.g., correlation, STTC).
- matrix
The n x n comparison matrix.
- Type:
np.ndarray
Examples
Creating a PairwiseCompMatrix:
>>> matrix = np.array([[1.0, 0.5], [0.5, 1.0]]) >>> pcm = PairwiseCompMatrix(matrix=matrix, labels=["A", "B"])
Exporting to NetworkX:
>>> G = pcm.to_networkx() >>> G = pcm.to_networkx(threshold=0.3) # Only edges with |weight| > 0.3 >>> G = pcm.to_networkx(invert_weights=True) # For shortest path algorithms
Getting a binary thresholded matrix:
>>> binary_pcm = pcm.threshold(0.4) # Values > 0.4 become 1, else 0
- to_networkx(threshold=None, invert_weights=False)[source]
Export the matrix to a NetworkX graph.
- Parameters:
threshold (float or None) – If provided, only edges with absolute weight > threshold will be included.
invert_weights (bool) – If True, edge weights are set to (1 - value) instead of value. This is useful for weighted network metrics like shortest path length, where strong correlations (e.g., 0.9) should represent short/cheap paths rather than long/expensive paths.
- Returns:
The exported graph.
- Return type:
G (networkx.Graph)
Notes
When using NetworkX for weighted shortest path algorithms (e.g.,
nx.shortest_path_length), edge weights are interpreted as distances. For correlation matrices where high values indicate strong relationships, setinvert_weights=Trueso that: - Strong correlation (0.9) -> weight 0.1 (short path) - Weak correlation (0.1) -> weight 0.9 (long path)
- threshold(threshold)[source]
Create a binary matrix based on a threshold.
- Parameters:
threshold (float) – Values with absolute value > threshold become 1, otherwise 0.
- Returns:
- A new PairwiseCompMatrix with binary
(0/1) values.
- Return type:
result (PairwiseCompMatrix)
Examples
>>> matrix = np.array([[1.0, 0.8, 0.2], [0.8, 1.0, 0.5], [0.2, 0.5, 1.0]]) >>> pcm = PairwiseCompMatrix(matrix=matrix) >>> binary_pcm = pcm.threshold(0.4) >>> print(binary_pcm.matrix) [[1. 1. 0.] [1. 1. 1.] [0. 1. 1.]]
- normalize(method='min_max', *, axis=None)[source]
Return a normalized copy of this matrix.
- Parameters:
method (str) – Normalization method. One of
"min_max"(scale to [0, 1]),"z_score"(subtract mean, divide by std),"row"(per-row min-max), or"col"(per-column min-max).axis (str or None) – When set to
"row"or"col", normalization is applied per-row or per-column instead of globally. When None (default), the entire matrix is normalized at once.
- Returns:
- A new PairwiseCompMatrix with
normalized values.
- Return type:
result (PairwiseCompMatrix)
Notes
NaN values are ignored during computation and preserved in the output.
For
"z_score", if the standard deviation is zero the result is filled with zeros (no division by zero).
- remove_by_condition(condition, op, threshold, fill=nan)[source]
Return a copy with entries removed where a condition matrix satisfies a comparison.
Entries where the comparison
op(condition, threshold)evaluates to True are replaced by fill; all other entries keep their original value from self.- Parameters:
condition (PairwiseCompMatrix) – Matrix to evaluate the comparison on. Must have the same shape as self.
op (str) – Comparison operator applied element-wise to the condition matrix. Standard:
"lt"(<),"le"(<=),"gt"(>),"ge"(>=),"eq"(==),"ne"(!=). Absolute-value variants:"abs_lt","abs_le","abs_gt","abs_ge"— these compare|condition|against the threshold.threshold (float) – Threshold value for the comparison.
fill (float) – Replacement value for removed entries (default: NaN).
- Returns:
- Copy of self where entries satisfying
the condition are replaced by fill. Labels and metadata are preserved from self.
- Return type:
result (PairwiseCompMatrix)
- extract_lower_triangle()[source]
Extract lower triangle (excluding diagonal) from this correlation matrix.
- Returns:
- Lower triangle values as a 1D array with
shape
(F,)where F = n*(n-1)/2.
- Return type:
values (np.ndarray)
- plot(ax=None, cmap=None, vmin=None, vmax=None, colorbar_label='', font_size=14, tick_labels=None, save_path=None)[source]
Plot the pairwise matrix as a heatmap.
- Parameters:
ax (matplotlib.axes.Axes or None) – Target axes. If None a standalone figure is created.
cmap (str or None) – Matplotlib colormap name. If None, auto-selects
"RdBu_r"for diverging data (contains both negative and positive values) or"viridis"otherwise.vmin (float or None) – Colormap minimum.
vmax (float or None) – Colormap maximum.
colorbar_label (str) – Label for the colorbar.
font_size (int) – Font size for labels and ticks.
tick_labels (list[str] or None) – Custom tick labels for both axes. If None, uses
self.labels(or integer indices when labels are not set).save_path (str or None) – If provided (and
axis None), save the figure to this path and close it.
- Returns:
(fig, ax)whenaxis None, otherwise justax.- Return type:
result
- extract_pairs_by_group(unit_labels)[source]
Extract upper-triangle pair values grouped by unit label combinations.
Given a label array of length N (one per unit), splits the upper triangle of the matrix into groups based on each pair’s label combination. For example, a boolean label
is_loweryields three groups:(False, False),(False, True),(True, True).- Parameters:
unit_labels (array-like) – Labels of length N assigning each unit to a group. Can be boolean, integer, or string values.
- Returns:
- Mapping from
(label_a, label_b)tuples to 1D arrays of pair values. Keys are canonically ordered so that
label_a <= label_b. Only groups with at least one pair are included. The values within each group preserve the order produced bynp.triu_indices, making results from different matrices with the same labels directly alignable for paired tests.
- Mapping from
- Return type:
groups (dict)
- plot_spatial_network(ax, positions, edge_threshold=None, top_pct=None, node_size_range=(2, 20), node_cmap='viridis', node_linewidth=0.2, edge_color='red', edge_linewidth=0.6, edge_alpha_range=(0.15, 1.0), scale_bar_um=500, font_size=None)[source]
Plot this pairwise matrix as a spatial network on MEA positions.
Unit positions must be supplied as positions – extract them from
SpikeData.neuron_attributes(e.g.np.array([[na['x'], na['y']] for na in sd.neuron_attributes])).Thin wrapper around
plot_utils.plot_spatial_network.- Parameters:
ax (matplotlib.axes.Axes) – Target axes.
positions (np.ndarray) – Unit positions, shape
(N, 2)with columns[x, y]in micrometres.edge_threshold (float or None) – Minimum matrix value to draw an edge.
top_pct (float or None) – Percentage of top edges to draw.
node_size_range (tuple) –
(min_size, max_size)in points² for scatter markers.node_cmap (str) – Matplotlib colourmap for node colour.
node_linewidth (float) – Outline width of node markers.
edge_color (str) – Colour for network edges.
edge_linewidth (float) – Line width for network edges.
edge_alpha_range (tuple) –
(min_alpha, max_alpha)for edge transparency.scale_bar_um (float) – Scale bar length in micrometres (0 to omit).
font_size (int or None) – Font size for scale bar label.
- Returns:
- The scatter
artist, useful for adding a colorbar.
- Return type:
scatter (matplotlib.collections.PathCollection)
- __init__(matrix, labels=None, metadata=<factory>)
PairwiseCompMatrixStack
- class spikelab.spikedata.pairwise.PairwiseCompMatrixStack(stack, labels=None, times=None, metadata=<factory>)[source]
Bases:
objectA data class for a stack of n x n pairwise comparison matrices (e.g., across slices or time bins).
- stack
The n x n x S stack of comparison matrices, where S is the number of slices.
- Type:
np.ndarray
- times
Time windows (start, end) associated with each matrix in the stack.
The stack supports flexible indexing:
Single index: Returns a PairwiseCompMatrix for that slice.
>>> stack[0] # First matrix as PairwiseCompMatrix
Slice: Returns a new PairwiseCompMatrixStack with the selected range.
>>> stack[0:5] # First 5 matrices as a new stack >>> stack[::2] # Every other matrix
Iteration: Iterate over all matrices in the stack.
>>> for matrix in stack: ... print(matrix.matrix.shape)
subslice(): Select specific non-contiguous slices by index.
>>> stack.subslice([0, 2, 5]) # Select slices 0, 2, and 5
Examples
Creating a stack:
>>> stack_data = np.random.rand(5, 5, 10) # 5x5 matrices, 10 slices >>> stack = PairwiseCompMatrixStack(stack=stack_data)
Slicing:
>>> sub_stack = stack[0:3] # Get first 3 slices >>> single_matrix = stack[5] # Get 6th slice as PairwiseCompMatrix
Binary thresholding:
>>> binary_stack = stack.threshold(0.5) # Threshold all matrices
- subslice(indices)[source]
Select specific slices from the stack by their indices.
- Parameters:
- Returns:
- A new stack containing only the
selected slices.
- Return type:
result (PairwiseCompMatrixStack)
Examples
>>> stack = PairwiseCompMatrixStack(stack=np.random.rand(5, 5, 10)) >>> sub = stack.subslice([0, 2, 5, 9]) # Select specific slices >>> len(sub) # 4
- threshold(threshold)[source]
Create a binary stack based on a threshold.
- Parameters:
threshold (float) – Values with absolute value > threshold become 1, otherwise 0.
- Returns:
- A new stack with binary (0/1)
values.
- Return type:
result (PairwiseCompMatrixStack)
Examples
>>> stack = PairwiseCompMatrixStack(stack=np.random.rand(5, 5, 10)) >>> binary_stack = stack.threshold(0.5)
- normalize(method='min_max', *, axis=None, per_slice=False)[source]
Return a normalized copy of this stack.
- Parameters:
method (str) – Normalization method (
"min_max","z_score","row", or"col"). SeePairwiseCompMatrix.normalizefor details.axis (str or None) –
"row"or"col"for per-row / per-column normalization within each N x N slice, or None for global normalization.per_slice (bool) – When True, each slice is normalized independently. When False (default), statistics are computed across the entire stack.
- Returns:
- A new stack with
normalized values.
- Return type:
result (PairwiseCompMatrixStack)
- remove_by_condition(condition, op, threshold, fill=nan)[source]
Return a copy with entries removed where a condition satisfies a comparison.
Entries where
op(condition, threshold)evaluates to True are replaced by fill; all other entries keep their original value from self. The condition is applied element-wise across all slices.- Parameters:
condition (PairwiseCompMatrix or PairwiseCompMatrixStack) – Matrix or stack to evaluate the comparison on. A single
PairwiseCompMatrixis broadcast across all slices. APairwiseCompMatrixStackmust have the same shape(N, N, S)as self.op (str) – Comparison operator applied element-wise to the condition. Standard:
"lt"(<),"le"(<=),"gt"(>),"ge"(>=),"eq"(==),"ne"(!=). Absolute-value variants:"abs_lt","abs_le","abs_gt","abs_ge"— these compare|condition|against the threshold.threshold (float) – Threshold value for the comparison.
fill (float) – Replacement value for removed entries (default: NaN).
- Returns:
- Copy of self where entries
satisfying the condition are replaced by fill. Labels, times, and metadata are preserved from self.
- Return type:
result (PairwiseCompMatrixStack)
- mean(ignore_nan=True)[source]
Compute the mean matrix across the stack.
- Parameters:
ignore_nan (bool) – Whether to use np.nanmean to ignore NaN values in the average.
- Returns:
- The element-wise mean across all
slices.
- Return type:
mean_matrix (PairwiseCompMatrix)
- plot_mean(ax=None, ignore_nan=True, cmap=None, vmin=None, vmax=None, colorbar_label='', font_size=14, tick_labels=None, save_path=None)[source]
Plot the mean matrix across all slices as a heatmap.
Computes
nanmean(ormean) over the stack axis and delegates toPairwiseCompMatrix.plot().- Parameters:
ax (matplotlib.axes.Axes or None) – Target axes. If None a standalone figure is created.
ignore_nan (bool) – Use
np.nanmeanto ignore NaN values.cmap (str or None) – Matplotlib colormap name. If None, auto-selects based on whether the mean matrix is diverging.
vmin (float or None) – Colormap minimum.
vmax (float or None) – Colormap maximum.
colorbar_label (str) – Label for the colorbar.
font_size (int) – Font size for labels and ticks.
tick_labels (list[str] or None) – Custom tick labels for both axes. If None, uses
self.labels(or integer indices when labels are not set).save_path (str or None) – If provided (and
axis None), save the figure to this path and close it.
- Returns:
(fig, ax)whenaxis None, otherwise justax.- Return type:
result
- extract_lower_triangle_features()[source]
Extract lower triangle (excluding diagonal) from each correlation matrix in the stack.
- Returns:
- 2D matrix of shape
(S, F)where each row contains lower triangle values for that correlation matrix. F = n*(n-1)/2 (number of unique pairs).
- 2D matrix of shape
- Return type:
features (np.ndarray)
- dim_red_on_lower_diagonal_corr_matrix(method='PCA', n_components=2, **kwargs)[source]
Apply dimensionality reduction (PCA or UMAP) to the lower triangle of each correlation matrix in the stack.
- Parameters:
- Returns:
- For PCA: a 3-tuple
(embedding, explained_variance_ratio, components)with shapes(S, n_components),(n_components,), and(n_components, F)whereF = N*(N-1)//2. For UMAP: a 2-tuple(embedding, trustworthiness)with embedding shape(S, n_components)and trustworthiness a float in [0, 1].
- Return type:
result (tuple)
- __init__(stack, labels=None, times=None, metadata=<factory>)