strip — Strip charts#
This module provides a StripChart class representing a
sliding strip chart, that is, a scatter plot where the number of points is limited
to a maximum, so that the thing acts essentially as a sliding window, typically in time.
This is mainly meant to represent the time history of a signal over a reasonable
span—a long-term acquisition might go on for weeks, and it would not make sense
to try and plot on the screen millions of points, but the last segment of the
acquisition is the most important part when we want to monitor what is happening.
Internally the class uses two distinct collections.deque objects to store
the data points, and the public interface is fairly simple:
you use
put()to add one or more data points (x and y coordinates) to the strip chart;you use
clear()to clear the contents of the strip chart;you use
set_max_length()to change the maximum length of the strip chart.
from aptapy.strip import StripChart
chart = StripChart(max_length=1000, label='Signal')
# add a single point
chart.put(0., 0.)
# add multiple points
chart.put([1., 2., 3.], [4., 5., 6.])
# plot the current contents of the strip chart
chart.plot()
See also
Have a look at the Simple strip chart and Interactive cursor examples.
Strip charts and wall time#
A fairly common use case for strip charts is to plot the time history of a signal
against wall time. In this case, the x-axis represents time in seconds since the
epoch (i.e., POSIX timestamps), e.g., from a call to time.time(). In order to
facilitate this use case, the module provides the EpochStripChart
class.
Note
time.time() always returns a floating-point number, representing seconds since the
Unix epoch (January 1, 1970, 00:00:00 UTC).
Note the UTC part: time.time() is not affected by the local time zone or daylight
saving time (not even mentioning leap seconds), and we do nothing clever internally
to this module to even try and keep track of any of that.
Internally, the class converts the seconds-since-epoch values to numpy datetime64
objects at plotting time. We support s, ms, us, and ns resolutions, with
the default being ms (milliseconds), see the EpochStripChart
documentation.
Note
datetime64 is the numpy native timestamp data type. Unlike Python’s datetime.datetime,
which stores a full object per entry, datetime64 is a compact numeric type that
stores timestamps as integer counts since the Unix epoch (1970-01-01) with a fixed
time unit. That time unit is specified in brackets, e.g., datetime64[s]
(second precision), datetime64[ms] (millisecond precision) and
datetime64[ns] (nanosecond precision).
In order to convert from POSIX timestamps (i.e., floating-point seconds since epoch)
to datetime64, numpy simply multiplies the floating-point number by the
appropriate factor (1 for seconds, 1000 for milliseconds and so on and so forth) and
then casts to integer. This is all done internally to the
EpochStripChart class. Good for you.
The class does its best to format the x-axis labels in a human-friendly way, so that the appearance is sensible regardless of the time span represented in the strip chart. Open an issue if you do run into an edge case!
See also
Have a look at the Epoch strip chart example.
Module documentation#
Strip charts.
- class aptapy.strip.StripChart(max_length: int = None, label: str = None, xlabel: str = None, ylabel: str = None)[source]#
Class describing a sliding strip chart, that is, a scatter plot where the number of points is limited to a maximum, so that the thing acts essentially as a sliding window, typically in time.
Arguments#
- max_lengthint, optional
the maximum number of points to keep in the strip chart. If None (the default), the number of points is unlimited.
- labelstr, optional
a text label for the data series (default is None).
- xlabelstr, optional
the label for the x axis.
- ylabelstr, optional
the label for the y axis.
- set_max_length(max_length: int) None[source]#
Set the maximum length of the strip chart.
Arguments#
- max_lengthint
the new maximum number of points to keep in the strip chart.
Note this creates two new deque objects under the hood but labels are preserved. There is no attempt to preserve existing data points.
- static _is_numerical_scalar(value) bool[source]#
Return whether the given value is a numerical scalar.
This is more tricky than one would expect as, while np.int32(1) and alike are instances of Number, 0-dim numpy arrays, e.g., numpy.array(1), are not.
- put(x: float | ndarray, y: float | ndarray) StripChart[source]#
Append data points to the strip chart.
This is supposed to correctly interoperate with all the data types we will be typically deal with: numbers, numpy scalars, and iterables, including numpy arrays.
Note this returns the strip chart itself in order to allow for chaining operations.
Arguments#
- xarray-like
The x value(s) to append to the strip chart.
- yarray-like
The y value(s) to append to the strip chart.
Returns#
- StripChart
The strip chart itself
- spline(k: int = 1, ext: str = 'raise') InterpolatedUnivariateSpline[source]#
Return an interpolating spline through all the underlying data points. This is useful, e.g., when adding a vertical cursor to the strip chart.
Note that, by default, the spline will raise a ValueError exception when asked to extrapolate outside the data range. (This plays well with the VerticalCursor class, as in that case the marker and associated text will be hidden.)
Arguments#
- kint
The order of the spline (default 1).
- extstr
The behavior when extrapolating outside the data range. Valid values are:
extrapolate(return the extrapolated value),zeros(return 0),raise(raise a ValueError), andconst(return the boundary value).
Returns#
- InterpolatedUnivariateSpline
The interpolating spline.
- _abc_impl = <_abc._abc_data object>#
- class aptapy.strip.EpochStripChart(max_length: int = None, label: str = '', xlabel: str = 'Date and Time (UTC)', ylabel: str = None, resolution: str = 'ms')[source]#
Class describing a sliding strip chart with epoch time on the x axis.
Operationally, this assumes that the values on the x axis are seconds since the Unix epoch (January 1st, 1970), e.g., from a time.time() call. These are then converted into NumPy datetime64 values (with the desired resolution) at plot time.
Arguments#
- max_lengthint, optional
the maximum number of points to keep in the strip chart. If None (the default), the number of points is unlimited.
- labelstr, optional
a text label for the data series (default is None).
- xlabelstr, optional
the label for the x axis.
- ylabelstr, optional
the label for the y axis.
- resolutionstr, optional
the resolution for the x axis. Supported values are “s” (seconds), “ms” (milliseconds), “us” (microseconds), and “ns” (nanoseconds). Default is “ms”.
- _RESOLUTION_MULTIPLIER_DICT = {'ms': 1000, 'ns': 1000000000, 's': 1, 'us': 1000000}#
- _render(axes: Axes = None, **kwargs) None[source]#
Plot the strip chart.
This is more tricky than one would expect, as NumPy’s datetime64 type stores timestamps as integer counts of a specific unit (like seconds, milliseconds, or nanoseconds) from the epoch. Assuming that we are using seconds since the epoch as input, we need to convert those into the appropriate integer counts. This boils down to using a multiplier depending on the desired resolution.
- _abc_impl = <_abc._abc_data object>#