# 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

    class SeriesScrollPlot(MplDrawer):
        """description"""

        @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()