Source code for draugr.drawers.mpl_drawers.series_scroll_plot

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


__author__ = "Christian Heider Nielsen"
__doc__ = r"""

           Created on 22/11/2019

           """

from typing import Sequence, Union

import numpy
from matplotlib import pyplot

from draugr.drawers.mpl_drawers.mpldrawer import MplDrawer
from draugr.numpy_utilities import recursive_flatten_numpy

__all__ = ["SeriesScrollPlot"]

from warg import passes_kws_to


[docs]class SeriesScrollPlot(MplDrawer): """description"""
[docs] @passes_kws_to(MplDrawer.__init__) def __init__( self, window_length: int = None, title: str = "", time_label: str = "Time", data_label: str = "Magnitude", reverse: bool = False, overwrite: bool = False, render: bool = True, **kws ): """ :param window_length: :param title: :param time_label: :param data_label: :param reverse: :param overwrite: :param placement: :param render:""" super().__init__(render=render, **kws) if not render: return self.overwrite = overwrite self.reverse = reverse self.window_length = window_length if window_length: assert window_length > 3 self.fig = pyplot.figure(figsize=(4, 4)) self.im = pyplot.plot([], []) if window_length: for i in range(len(self.im)): self.im[i].set_xdata(range(window_length)) self.im[i].set_ydata([numpy.nan] * window_length) pyplot.xlim(0, window_length) pyplot.xlabel(time_label) pyplot.ylabel(data_label) pyplot.title(title) pyplot.tight_layout()
def _draw(self, data: Union[Sequence, int, float, complex]): """ SHOULD NOT BE CALLED DIRECTLY! :param data: :return:""" if not isinstance(data, Sequence): data = [data] data = recursive_flatten_numpy(data) num_images = len(self.im) num_series = len(data) min_min, max_max = None, None if num_images != num_series: # print('Reinstantiating figures') self.im = pyplot.plot(*[[] for _ in range(num_series)] * 2) if self.window_length: for i in range(len(self.im)): self.im[i].set_xdata(range(self.window_length)) self.im[i].set_ydata([numpy.nan] * self.window_length) for i in range(num_images): time_points = self.im[i].get_xdata() data_points = self.im[i].get_ydata() if self.window_length: if not self.overwrite: if not self.reverse: data_points = numpy.concatenate( (data_points[1:], [data[i]]), axis=0 ) else: data_points = numpy.concatenate( ([data[i]], data_points[:-1]), axis=0 ) else: if not self.reverse: data_points[self.n % self.window_length] = data[i] else: data_points[ self.window_length - 1 - self.n % self.window_length ] = data[i] else: if not self.reverse: time_points = numpy.concatenate((time_points, [self.n]), axis=0) data_points = numpy.concatenate((data_points, [data[i]]), axis=0) else: time_points = numpy.concatenate(([self.n], time_points), axis=0) data_points = numpy.concatenate(([data[i]], data_points), axis=0) pyplot.xlim(0, self.n + 1) self.im[i].set_xdata(time_points) self.im[i].set_ydata(data_points) min_, max_ = numpy.nanmin(data_points), numpy.nanmax(data_points) if min_min is None or min_ < min_min: min_min = min_ if max_max is None or max_ > max_max: max_max = max_ if min_min == max_max: max_max += 1 pyplot.ylim(min_min, max_max)
if __name__ == "__main__": def asidjas() -> None: """ :rtype: None """ from math import cos, sin def multi_series(): """description""" s = SeriesScrollPlot( window_length=200, reverse=False, overwrite=False, default_delta=None ) for i in range(1000): s.draw([sin(i / 100) * 2, cos(i / 10)]) def single_series(): """description""" s = SeriesScrollPlot(window_length=200, reverse=False, overwrite=False) for i in range(1000): s.draw([sin(i / 20)], 1.0 / 60.0) def single_series_no_wrap(): """description""" s = SeriesScrollPlot(window_length=200, reverse=True, overwrite=False) for i in range(1000): s.draw(sin(i / 20), 1.0 / 60.0) def single_series_no_wrap_rescale(): """description""" s = SeriesScrollPlot(window_length=100, reverse=True, overwrite=False) for i in range(1000): s.draw(sin(i / 100), 1.0 / 60.0) multi_series() asidjas()