Source code for micropython_uplot.scatter

# SPDX-FileCopyrightText: Copyright (c) 2023 Jose D. Montoya
#
# SPDX-License-Identifier: MIT
"""
`scatter`
================================================================================

scatter plot for micropython_uplot


* Author: Jose D. Montoya


"""
from array import array
from micropython_uplot.colors import set_color

try:
    from typing import Union, Optional
    from micropython_uplot.plot import PLOT
except ImportError:
    pass

__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/jposada202020/MicroPython_UPLOT.git"


_TRIANGLE = array("i", [0, 0, 8, 0, 4, -7])
_SQUARE = array("i", [0, 0, 6, 0, 6, -6, 0, -6])
_DIAMOND = array("i", [0, 0, 3, -4, 6, 0, 3, 4])


[docs] class Scatter: """ Main class to display different graphics """ def __init__( self, plot: PLOT, x: list, y: list, rangex: Optional[list] = None, rangey: Optional[list] = None, radius: Optional[Union[list, int]] = 3, pointer_color: tuple = (0, 255, 0), pointer: Optional[str] = None, pointer_index: Optional[int] = None, ) -> None: """ :param plot: Plot object for the scatter to be drawn :param x: x points coordinates :param y: y points coordinates :param list|None rangex: x range limits :param list|None rangey: y range limits :param int|list radius: circle radius :param int pointer_color: pointer color. Default is 0xFF905D :param str|None pointer: pointer shape. :param int|None pointer_index: pointer index. Default is None """ if pointer is None: self._pointer = "circle" else: self._pointer = pointer if pointer_index is None: self._pointer_index = plot._pointer_index else: self._pointer_index = pointer_index self._radius = radius self._pointer_color = set_color( plot._display, self._pointer_index, pointer_color[0], pointer_color[1], pointer_color[2], ) plot._pointer_index += 1 if isinstance(self._radius, list) and self._pointer != "circle": raise ValueError( f"Pointer paramater is {self._pointer}. Variable Radius are not accepted" ) max_x = max(x) min_x = min(x) max_y = max(y) min_y = min(y) if rangex is None: xmin = min_x - (abs(max_x - min_x) / 10) xmax = max_x + (abs(max_x - min_x) / 10) else: xmin = min(rangex) xmax = max(rangex) if rangey is None: ymin = min_y - (abs(max_y - min_y) / 10) ymax = max_y + (abs(max_y - min_y) / 10) else: ymin = min(rangey) ymax = max(rangey) self._xnorm = tuple( [ int(plot.transform(xmin, xmax, plot._newxmin, plot._newxmax, _)) for _ in x ] ) self._ynorm = tuple( [ int(plot.transform(ymin, ymax, plot._newymin, plot._newymax, _)) for _ in y ] ) self._draw_pointer(plot) if plot._scatterfirst: if plot._showticks: plot._draw_ticks(x, y) plot._scatterfirst = False plot._showticks = False def _draw_pointer(self, plot: PLOT) -> None: """ :param PLOT plot: Plot object for the scatter to be drawn """ if isinstance(self._radius, list): for i, _ in enumerate(self._xnorm): plot._display.ellipse( self._xnorm[i], self._ynorm[i], self._radius[i], self._radius[i], self._pointer_color, True, ) else: for i, _ in enumerate(self._xnorm): if self._pointer == "circle": plot._display.ellipse( self._xnorm[i], self._ynorm[i], self._radius, self._radius, self._pointer_color, True, ) elif self._pointer == "triangle": plot._display.poly( self._xnorm[i], self._ynorm[i], _TRIANGLE, self._pointer_color, True, ) elif self._pointer == "square": plot._display.poly( self._xnorm[i], self._ynorm[i], _SQUARE, self._pointer_color, True, ) elif self._pointer == "diamond": plot._display.poly( self._xnorm[i], self._ynorm[i], _DIAMOND, self._pointer_color, True, )
[docs] class Pointer: """ Pointer container class """ CIRCLE = "circle" TRIANGLE = "triangle" SQUARE = "square" DIAMOND = "diamond"