ezmsg.tools.plot#
Putting ezmsg streams onto phosphor plots.
describe is the pure half – given dims, axes and attrs, work out what
is being plotted – and imports neither Qt nor phosphor, so it is usable from a
topic subscriber, a shared-memory mirror, or a test with neither.
shmem_sweep is the Qt widget built on it, and needs the viewer or
sigmon extra.
ShmemSweepWidget and layout are resolved lazily so that importing this package, or
anything under it, does not pull in Qt. Eagerly importing it here would make
from ezmsg.tools.plot.describe import ... fail without phosphor installed,
since importing a submodule runs its parent’s __init__ first – which would
put a GPU stack behind a module that deliberately has no rendering dependency
at all.
- class MetricSpec(axis, labels, kind)[source]#
Bases:
NamedTupleA trailing per-sample tuple: what it is called and what it holds.
- class StreamShape(n_channels, srate, channel_labels, metric, unit)[source]#
Bases:
NamedTupleWhat a plot needs to know about an incoming stream.
- Parameters:
- srate: float#
Samples per second of the pushed stream. For an envelope this is the bucket rate, not the rate before decimation – which is what a sweep buffer must be sized with, or its ring is longer than the data arriving to fill it.
- metric: MetricSpec | None#
The trailing per-sample tuple, if the stream carries one.
- exception UnsupportedMetricError[source]#
Bases:
NotImplementedErrorA recognised metric axis that no renderer here can draw yet.
- describe_axisarray(msg, *, time_axis='time', label_fields=('label',))[source]#
Describe a stream from one of its
AxisArraymessages.- Parameters:
- Return type:
- describe_mirror(mirror, *, time_axis='time', label_fields=('label',))[source]#
Describe a stream from a connected
EZShmMirror.Returns None until the writer has published both a valid buffer header and its metadata – the two arrive independently, and a description built from only one of them would be missing either the shape or the names.
- Parameters:
- Return type:
StreamShape | None
- flatten_for_plot(data, shape)[source]#
Reshape a block to what a plot’s
push_dataexpects.(n_samples, n_channels, k)when the stream carries a k-wide metric tuple,(n_samples, n_channels)otherwise, with any other dimensions folded into channels.The metric case is the reason this exists. Folding a
(time, ch, 2)block into(time, ch * 2)– which is what a naivereshapedoes – renders as twice as many traces, alternating the two metrics, with every channel label off by a factor of two. It looks like data, so nothing complains.- Parameters:
data (ndarray)
shape (StreamShape)
- Return type:
- metric_axis(dims, axes)[source]#
Describe the trailing per-sample tuple, or None if there is not one.
Recognised by labels, not by name or width. The name only narrows the search; the labels are what distinguish a (min, max) envelope from a (mean, std) dispersion pair, which is the same shape and must not be drawn the same way.
Returns a spec for any tuple in
METRIC_KINDS, including ones no renderer here supports yet – describing a stream is not the same as being able to draw it, and a caller that only wants to know what arrived should not have to catch an exception. Seerequire_sweep_renderable()for the capability check.
- require_sweep_renderable(shape)[source]#
Raise if a sweep plot cannot draw this stream’s metric axis.
- Raises:
UnsupportedMetricError – for a recognised metric a sweep cannot draw.
- Parameters:
shape (StreamShape)
- Return type:
None
Modules