ezmsg.tools.plot.layout#

Turning a structured ch coordinate axis into a per-channel grid layout.

The geometry counterpart to ezmsg.tools.chmeta, which does the same job for names. An AxisArray’s ch axis may carry electrode coordinates; a grid plot wants positions, sizes and labels. Which fields those live in is a property of the acquisition system, so the decoding belongs here rather than in phosphor, whose grids take plain arrays and have no opinion about where they came from.

Everything degrades: a source with no ch axis at all, or one carrying names but no coordinates, still gets a layout – a square-ish tiling – because a plot that draws nothing is less useful than one that draws the right number of cells in the wrong places.

Functions

channel_layout(ch_axis_data, n_ch, *, position_fields=('x', 'y'), size_field='size', group_field='headstage', label_fields=('label',))[source]#

Per-channel (positions, sizes, labels) for a grid plot.

Parameters:
  • ch_axis_data (ndarray | None) – The ch axis’ structured data, or None when the stream carries no channel metadata.

  • n_ch (int) – Channels in the data, used when the axis cannot say.

  • position_fields (Tuple[str, str]) – Fields holding each channel’s coordinates. Both must be present, or the layout falls back to a tiling.

  • size_field (str) – Field holding each channel’s extent. Absent gives None, which lets the renderer size cells by the inferred pitch.

  • group_field (str | None) – Field identifying which device a channel belongs to. Devices commonly number their electrodes from a shared origin, so without this two of them draw on top of each other. None skips the check.

  • label_fields (Sequence[str]) – Passed to channel_names().

Returns:

positions as (n, 2) float32, sizes as (n,) float32 or None, and one label per channel.

Return type:

Tuple[ndarray, ndarray | None, List[str]]

Classes

class ChannelLayoutCache[source]#

Bases: object

channel_layout(), recomputed only when the axis actually changes.

A grid that derives its layout per message pays for it per message, while the answer changes about once a session. Fingerprinting the axis costs around 1 us against the 75 us the derivation takes, so this is worth having wherever messages arrive faster than the geometry does.

Deliberately a cache rather than a shared instance: two widgets watching one stream each keep their own, so neither has to know the other exists, and the derivation stays where any application can call it.

__init__()[source]#
Return type:

None

class ChannelLayoutCache[source]#

Bases: object

channel_layout(), recomputed only when the axis actually changes.

A grid that derives its layout per message pays for it per message, while the answer changes about once a session. Fingerprinting the axis costs around 1 us against the 75 us the derivation takes, so this is worth having wherever messages arrive faster than the geometry does.

Deliberately a cache rather than a shared instance: two widgets watching one stream each keep their own, so neither has to know the other exists, and the derivation stays where any application can call it.

__init__()[source]#
Return type:

None

channel_layout(ch_axis_data, n_ch, *, position_fields=('x', 'y'), size_field='size', group_field='headstage', label_fields=('label',))[source]#

Per-channel (positions, sizes, labels) for a grid plot.

Parameters:
  • ch_axis_data (ndarray | None) – The ch axis’ structured data, or None when the stream carries no channel metadata.

  • n_ch (int) – Channels in the data, used when the axis cannot say.

  • position_fields (Tuple[str, str]) – Fields holding each channel’s coordinates. Both must be present, or the layout falls back to a tiling.

  • size_field (str) – Field holding each channel’s extent. Absent gives None, which lets the renderer size cells by the inferred pitch.

  • group_field (str | None) – Field identifying which device a channel belongs to. Devices commonly number their electrodes from a shared origin, so without this two of them draw on top of each other. None skips the check.

  • label_fields (Sequence[str]) – Passed to channel_names().

Returns:

positions as (n, 2) float32, sizes as (n,) float32 or None, and one label per channel.

Return type:

Tuple[ndarray, ndarray | None, List[str]]