Buckets:
| r""" | |
| Functions to handle markers; used by the marker functionality of | |
| `~matplotlib.axes.Axes.plot`, `~matplotlib.axes.Axes.scatter`, and | |
| `~matplotlib.axes.Axes.errorbar`. | |
| All possible markers are defined here: | |
| ============================== ====== ========================================= | |
| marker symbol description | |
| ============================== ====== ========================================= | |
| ``"."`` |m00| point | |
| ``","`` |m01| pixel | |
| ``"o"`` |m02| circle | |
| ``"v"`` |m03| triangle_down | |
| ``"^"`` |m04| triangle_up | |
| ``"<"`` |m05| triangle_left | |
| ``">"`` |m06| triangle_right | |
| ``"1"`` |m07| tri_down | |
| ``"2"`` |m08| tri_up | |
| ``"3"`` |m09| tri_left | |
| ``"4"`` |m10| tri_right | |
| ``"8"`` |m11| octagon | |
| ``"s"`` |m12| square | |
| ``"p"`` |m13| pentagon | |
| ``"P"`` |m23| plus (filled) | |
| ``"*"`` |m14| star | |
| ``"h"`` |m15| hexagon1 | |
| ``"H"`` |m16| hexagon2 | |
| ``"+"`` |m17| plus | |
| ``"x"`` |m18| x | |
| ``"X"`` |m24| x (filled) | |
| ``"D"`` |m19| diamond | |
| ``"d"`` |m20| thin_diamond | |
| ``"|"`` |m21| vline | |
| ``"_"`` |m22| hline | |
| ``0`` (``TICKLEFT``) |m25| tickleft | |
| ``1`` (``TICKRIGHT``) |m26| tickright | |
| ``2`` (``TICKUP``) |m27| tickup | |
| ``3`` (``TICKDOWN``) |m28| tickdown | |
| ``4`` (``CARETLEFT``) |m29| caretleft | |
| ``5`` (``CARETRIGHT``) |m30| caretright | |
| ``6`` (``CARETUP``) |m31| caretup | |
| ``7`` (``CARETDOWN``) |m32| caretdown | |
| ``8`` (``CARETLEFTBASE``) |m33| caretleft (centered at base) | |
| ``9`` (``CARETRIGHTBASE``) |m34| caretright (centered at base) | |
| ``10`` (``CARETUPBASE``) |m35| caretup (centered at base) | |
| ``11`` (``CARETDOWNBASE``) |m36| caretdown (centered at base) | |
| ``"none"`` or ``"None"`` nothing | |
| ``" "`` or ``""`` nothing | |
| ``"$...$"`` |m37| Render the string using mathtext. | |
| E.g ``"$f$"`` for marker showing the | |
| letter ``f``. | |
| ``verts`` A list of (x, y) pairs used for Path | |
| vertices. The center of the marker is | |
| located at (0, 0) and the size is | |
| normalized, such that the created path | |
| is encapsulated inside the unit cell. | |
| ``path`` A `~matplotlib.path.Path` instance. | |
| ``(numsides, 0, angle)`` A regular polygon with ``numsides`` | |
| sides, rotated by ``angle``. | |
| ``(numsides, 1, angle)`` A star-like symbol with ``numsides`` | |
| sides, rotated by ``angle``. | |
| ``(numsides, 2, angle)`` An asterisk with ``numsides`` sides, | |
| rotated by ``angle``. | |
| ============================== ====== ========================================= | |
| Note that special symbols can be defined via the | |
| :ref:`STIX math font <mathtext>`, | |
| e.g. ``"$\u266B$"``. For an overview over the STIX font symbols refer to the | |
| `STIX font table <http://www.stixfonts.org/allGlyphs.html>`_. | |
| Also see the :doc:`/gallery/text_labels_and_annotations/stix_fonts_demo`. | |
| Integer numbers from ``0`` to ``11`` create lines and triangles. Those are | |
| equally accessible via capitalized variables, like ``CARETDOWNBASE``. | |
| Hence the following are equivalent:: | |
| plt.plot([1, 2, 3], marker=11) | |
| plt.plot([1, 2, 3], marker=matplotlib.markers.CARETDOWNBASE) | |
| Markers join and cap styles can be customized by creating a new instance of | |
| MarkerStyle. | |
| A MarkerStyle can also have a custom `~matplotlib.transforms.Transform` | |
| allowing it to be arbitrarily rotated or offset. | |
| Examples showing the use of markers: | |
| * :doc:`/gallery/lines_bars_and_markers/marker_reference` | |
| * :doc:`/gallery/lines_bars_and_markers/scatter_star_poly` | |
| * :doc:`/gallery/lines_bars_and_markers/multivariate_marker_plot` | |
| .. |m00| image:: /_static/markers/m00.png | |
| .. |m01| image:: /_static/markers/m01.png | |
| .. |m02| image:: /_static/markers/m02.png | |
| .. |m03| image:: /_static/markers/m03.png | |
| .. |m04| image:: /_static/markers/m04.png | |
| .. |m05| image:: /_static/markers/m05.png | |
| .. |m06| image:: /_static/markers/m06.png | |
| .. |m07| image:: /_static/markers/m07.png | |
| .. |m08| image:: /_static/markers/m08.png | |
| .. |m09| image:: /_static/markers/m09.png | |
| .. |m10| image:: /_static/markers/m10.png | |
| .. |m11| image:: /_static/markers/m11.png | |
| .. |m12| image:: /_static/markers/m12.png | |
| .. |m13| image:: /_static/markers/m13.png | |
| .. |m14| image:: /_static/markers/m14.png | |
| .. |m15| image:: /_static/markers/m15.png | |
| .. |m16| image:: /_static/markers/m16.png | |
| .. |m17| image:: /_static/markers/m17.png | |
| .. |m18| image:: /_static/markers/m18.png | |
| .. |m19| image:: /_static/markers/m19.png | |
| .. |m20| image:: /_static/markers/m20.png | |
| .. |m21| image:: /_static/markers/m21.png | |
| .. |m22| image:: /_static/markers/m22.png | |
| .. |m23| image:: /_static/markers/m23.png | |
| .. |m24| image:: /_static/markers/m24.png | |
| .. |m25| image:: /_static/markers/m25.png | |
| .. |m26| image:: /_static/markers/m26.png | |
| .. |m27| image:: /_static/markers/m27.png | |
| .. |m28| image:: /_static/markers/m28.png | |
| .. |m29| image:: /_static/markers/m29.png | |
| .. |m30| image:: /_static/markers/m30.png | |
| .. |m31| image:: /_static/markers/m31.png | |
| .. |m32| image:: /_static/markers/m32.png | |
| .. |m33| image:: /_static/markers/m33.png | |
| .. |m34| image:: /_static/markers/m34.png | |
| .. |m35| image:: /_static/markers/m35.png | |
| .. |m36| image:: /_static/markers/m36.png | |
| .. |m37| image:: /_static/markers/m37.png | |
| """ | |
| import copy | |
| from collections.abc import Sized | |
| import numpy as np | |
| import matplotlib as mpl | |
| from . import _api, cbook | |
| from .path import Path | |
| from .transforms import IdentityTransform, Affine2D | |
| from ._enums import JoinStyle, CapStyle | |
| # special-purpose marker identifiers: | |
| (TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN, | |
| CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN, | |
| CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE) = range(12) | |
| _empty_path = Path(np.empty((0, 2))) | |
| class MarkerStyle: | |
| """ | |
| A class representing marker types. | |
| Instances are immutable. If you need to change anything, create a new | |
| instance. | |
| Attributes | |
| ---------- | |
| markers : dict | |
| All known markers. | |
| filled_markers : tuple | |
| All known filled markers. This is a subset of *markers*. | |
| fillstyles : tuple | |
| The supported fillstyles. | |
| """ | |
| markers = { | |
| '.': 'point', | |
| ',': 'pixel', | |
| 'o': 'circle', | |
| 'v': 'triangle_down', | |
| '^': 'triangle_up', | |
| '<': 'triangle_left', | |
| '>': 'triangle_right', | |
| '1': 'tri_down', | |
| '2': 'tri_up', | |
| '3': 'tri_left', | |
| '4': 'tri_right', | |
| '8': 'octagon', | |
| 's': 'square', | |
| 'p': 'pentagon', | |
| '*': 'star', | |
| 'h': 'hexagon1', | |
| 'H': 'hexagon2', | |
| '+': 'plus', | |
| 'x': 'x', | |
| 'D': 'diamond', | |
| 'd': 'thin_diamond', | |
| '|': 'vline', | |
| '_': 'hline', | |
| 'P': 'plus_filled', | |
| 'X': 'x_filled', | |
| TICKLEFT: 'tickleft', | |
| TICKRIGHT: 'tickright', | |
| TICKUP: 'tickup', | |
| TICKDOWN: 'tickdown', | |
| CARETLEFT: 'caretleft', | |
| CARETRIGHT: 'caretright', | |
| CARETUP: 'caretup', | |
| CARETDOWN: 'caretdown', | |
| CARETLEFTBASE: 'caretleftbase', | |
| CARETRIGHTBASE: 'caretrightbase', | |
| CARETUPBASE: 'caretupbase', | |
| CARETDOWNBASE: 'caretdownbase', | |
| "None": 'nothing', | |
| "none": 'nothing', | |
| ' ': 'nothing', | |
| '': 'nothing' | |
| } | |
| # Just used for informational purposes. is_filled() | |
| # is calculated in the _set_* functions. | |
| filled_markers = ( | |
| '.', 'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd', | |
| 'P', 'X') | |
| fillstyles = ('full', 'left', 'right', 'bottom', 'top', 'none') | |
| _half_fillstyles = ('left', 'right', 'bottom', 'top') | |
| def __init__(self, marker, | |
| fillstyle=None, transform=None, capstyle=None, joinstyle=None): | |
| """ | |
| Parameters | |
| ---------- | |
| marker : str, array-like, Path, MarkerStyle | |
| - Another instance of `MarkerStyle` copies the details of that *marker*. | |
| - For other possible marker values, see the module docstring | |
| `matplotlib.markers`. | |
| fillstyle : str, default: :rc:`markers.fillstyle` | |
| One of 'full', 'left', 'right', 'bottom', 'top', 'none'. | |
| transform : `~matplotlib.transforms.Transform`, optional | |
| Transform that will be combined with the native transform of the | |
| marker. | |
| capstyle : `.CapStyle` or %(CapStyle)s, optional | |
| Cap style that will override the default cap style of the marker. | |
| joinstyle : `.JoinStyle` or %(JoinStyle)s, optional | |
| Join style that will override the default join style of the marker. | |
| """ | |
| self._marker_function = None | |
| self._user_transform = transform | |
| self._user_capstyle = CapStyle(capstyle) if capstyle is not None else None | |
| self._user_joinstyle = JoinStyle(joinstyle) if joinstyle is not None else None | |
| self._set_fillstyle(fillstyle) | |
| self._set_marker(marker) | |
| def _recache(self): | |
| if self._marker_function is None: | |
| return | |
| self._path = _empty_path | |
| self._transform = IdentityTransform() | |
| self._alt_path = None | |
| self._alt_transform = None | |
| self._snap_threshold = None | |
| self._joinstyle = JoinStyle.round | |
| self._capstyle = self._user_capstyle or CapStyle.butt | |
| # Initial guess: Assume the marker is filled unless the fillstyle is | |
| # set to 'none'. The marker function will override this for unfilled | |
| # markers. | |
| self._filled = self._fillstyle != 'none' | |
| self._marker_function() | |
| def __bool__(self): | |
| return bool(len(self._path.vertices)) | |
| def is_filled(self): | |
| return self._filled | |
| def get_fillstyle(self): | |
| return self._fillstyle | |
| def _set_fillstyle(self, fillstyle): | |
| """ | |
| Set the fillstyle. | |
| Parameters | |
| ---------- | |
| fillstyle : {'full', 'left', 'right', 'bottom', 'top', 'none'} | |
| The part of the marker surface that is colored with | |
| markerfacecolor. | |
| """ | |
| if fillstyle is None: | |
| fillstyle = mpl.rcParams['markers.fillstyle'] | |
| _api.check_in_list(self.fillstyles, fillstyle=fillstyle) | |
| self._fillstyle = fillstyle | |
| def get_joinstyle(self): | |
| return self._joinstyle.name | |
| def get_capstyle(self): | |
| return self._capstyle.name | |
| def get_marker(self): | |
| return self._marker | |
| def _set_marker(self, marker): | |
| """ | |
| Set the marker. | |
| Parameters | |
| ---------- | |
| marker : str, array-like, Path, MarkerStyle | |
| - Another instance of `MarkerStyle` copies the details of that *marker*. | |
| - For other possible marker values see the module docstring | |
| `matplotlib.markers`. | |
| """ | |
| if isinstance(marker, str) and cbook.is_math_text(marker): | |
| self._marker_function = self._set_mathtext_path | |
| elif isinstance(marker, (int, str)) and marker in self.markers: | |
| self._marker_function = getattr(self, '_set_' + self.markers[marker]) | |
| elif (isinstance(marker, np.ndarray) and marker.ndim == 2 and | |
| marker.shape[1] == 2): | |
| self._marker_function = self._set_vertices | |
| elif isinstance(marker, Path): | |
| self._marker_function = self._set_path_marker | |
| elif (isinstance(marker, Sized) and len(marker) in (2, 3) and | |
| marker[1] in (0, 1, 2)): | |
| self._marker_function = self._set_tuple_marker | |
| elif isinstance(marker, MarkerStyle): | |
| self.__dict__ = copy.deepcopy(marker.__dict__) | |
| else: | |
| try: | |
| Path(marker) | |
| self._marker_function = self._set_vertices | |
| except ValueError as err: | |
| raise ValueError( | |
| f'Unrecognized marker style {marker!r}') from err | |
| if not isinstance(marker, MarkerStyle): | |
| self._marker = marker | |
| self._recache() | |
| def get_path(self): | |
| """ | |
| Return a `.Path` for the primary part of the marker. | |
| For unfilled markers this is the whole marker, for filled markers, | |
| this is the area to be drawn with *markerfacecolor*. | |
| """ | |
| return self._path | |
| def get_transform(self): | |
| """ | |
| Return the transform to be applied to the `.Path` from | |
| `MarkerStyle.get_path()`. | |
| """ | |
| if self._user_transform is None: | |
| return self._transform.frozen() | |
| else: | |
| return (self._transform + self._user_transform).frozen() | |
| def get_alt_path(self): | |
| """ | |
| Return a `.Path` for the alternate part of the marker. | |
| For unfilled markers, this is *None*; for filled markers, this is the | |
| area to be drawn with *markerfacecoloralt*. | |
| """ | |
| return self._alt_path | |
| def get_alt_transform(self): | |
| """ | |
| Return the transform to be applied to the `.Path` from | |
| `MarkerStyle.get_alt_path()`. | |
| """ | |
| if self._user_transform is None: | |
| return self._alt_transform.frozen() | |
| else: | |
| return (self._alt_transform + self._user_transform).frozen() | |
| def get_snap_threshold(self): | |
| return self._snap_threshold | |
| def get_user_transform(self): | |
| """Return user supplied part of marker transform.""" | |
| if self._user_transform is not None: | |
| return self._user_transform.frozen() | |
| def transformed(self, transform): | |
| """ | |
| Return a new version of this marker with the transform applied. | |
| Parameters | |
| ---------- | |
| transform : `~matplotlib.transforms.Affine2D` | |
| Transform will be combined with current user supplied transform. | |
| """ | |
| new_marker = MarkerStyle(self) | |
| if new_marker._user_transform is not None: | |
| new_marker._user_transform += transform | |
| else: | |
| new_marker._user_transform = transform | |
| return new_marker | |
| def rotated(self, *, deg=None, rad=None): | |
| """ | |
| Return a new version of this marker rotated by specified angle. | |
| Parameters | |
| ---------- | |
| deg : float, optional | |
| Rotation angle in degrees. | |
| rad : float, optional | |
| Rotation angle in radians. | |
| .. note:: You must specify exactly one of deg or rad. | |
| """ | |
| if deg is None and rad is None: | |
| raise ValueError('One of deg or rad is required') | |
| if deg is not None and rad is not None: | |
| raise ValueError('Only one of deg and rad can be supplied') | |
| new_marker = MarkerStyle(self) | |
| if new_marker._user_transform is None: | |
| new_marker._user_transform = Affine2D() | |
| if deg is not None: | |
| new_marker._user_transform.rotate_deg(deg) | |
| if rad is not None: | |
| new_marker._user_transform.rotate(rad) | |
| return new_marker | |
| def scaled(self, sx, sy=None): | |
| """ | |
| Return new marker scaled by specified scale factors. | |
| If *sy* is not given, the same scale is applied in both the *x*- and | |
| *y*-directions. | |
| Parameters | |
| ---------- | |
| sx : float | |
| *X*-direction scaling factor. | |
| sy : float, optional | |
| *Y*-direction scaling factor. | |
| """ | |
| if sy is None: | |
| sy = sx | |
| new_marker = MarkerStyle(self) | |
| _transform = new_marker._user_transform or Affine2D() | |
| new_marker._user_transform = _transform.scale(sx, sy) | |
| return new_marker | |
| def _set_nothing(self): | |
| self._filled = False | |
| def _set_custom_marker(self, path): | |
| rescale = np.max(np.abs(path.vertices)) # max of x's and y's. | |
| self._transform = Affine2D().scale(0.5 / rescale) | |
| self._path = path | |
| def _set_path_marker(self): | |
| self._set_custom_marker(self._marker) | |
| def _set_vertices(self): | |
| self._set_custom_marker(Path(self._marker)) | |
| def _set_tuple_marker(self): | |
| marker = self._marker | |
| if len(marker) == 2: | |
| numsides, rotation = marker[0], 0.0 | |
| elif len(marker) == 3: | |
| numsides, rotation = marker[0], marker[2] | |
| symstyle = marker[1] | |
| if symstyle == 0: | |
| self._path = Path.unit_regular_polygon(numsides) | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| elif symstyle == 1: | |
| self._path = Path.unit_regular_star(numsides) | |
| self._joinstyle = self._user_joinstyle or JoinStyle.bevel | |
| elif symstyle == 2: | |
| self._path = Path.unit_regular_asterisk(numsides) | |
| self._filled = False | |
| self._joinstyle = self._user_joinstyle or JoinStyle.bevel | |
| else: | |
| raise ValueError(f"Unexpected tuple marker: {marker}") | |
| self._transform = Affine2D().scale(0.5).rotate_deg(rotation) | |
| def _set_mathtext_path(self): | |
| """ | |
| Draw mathtext markers '$...$' using `.TextPath` object. | |
| Submitted by tcb | |
| """ | |
| from matplotlib.text import TextPath | |
| # again, the properties could be initialised just once outside | |
| # this function | |
| text = TextPath(xy=(0, 0), s=self.get_marker(), | |
| usetex=mpl.rcParams['text.usetex']) | |
| if len(text.vertices) == 0: | |
| return | |
| bbox = text.get_extents() | |
| max_dim = max(bbox.width, bbox.height) | |
| self._transform = ( | |
| Affine2D() | |
| .translate(-bbox.xmin + 0.5 * -bbox.width, -bbox.ymin + 0.5 * -bbox.height) | |
| .scale(1.0 / max_dim)) | |
| self._path = text | |
| self._snap = False | |
| def _half_fill(self): | |
| return self.get_fillstyle() in self._half_fillstyles | |
| def _set_circle(self, size=1.0): | |
| self._transform = Affine2D().scale(0.5 * size) | |
| self._snap_threshold = np.inf | |
| if not self._half_fill(): | |
| self._path = Path.unit_circle() | |
| else: | |
| self._path = self._alt_path = Path.unit_circle_righthalf() | |
| fs = self.get_fillstyle() | |
| self._transform.rotate_deg( | |
| {'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs]) | |
| self._alt_transform = self._transform.frozen().rotate_deg(180.) | |
| def _set_point(self): | |
| self._set_circle(size=0.5) | |
| def _set_pixel(self): | |
| self._path = Path.unit_rectangle() | |
| # Ideally, you'd want -0.5, -0.5 here, but then the snapping | |
| # algorithm in the Agg backend will round this to a 2x2 | |
| # rectangle from (-1, -1) to (1, 1). By offsetting it | |
| # slightly, we can force it to be (0, 0) to (1, 1), which both | |
| # makes it only be a single pixel and places it correctly | |
| # aligned to 1-width stroking (i.e. the ticks). This hack is | |
| # the best of a number of bad alternatives, mainly because the | |
| # backends are not aware of what marker is actually being used | |
| # beyond just its path data. | |
| self._transform = Affine2D().translate(-0.49999, -0.49999) | |
| self._snap_threshold = None | |
| _triangle_path = Path._create_closed([[0, 1], [-1, -1], [1, -1]]) | |
| # Going down halfway looks to small. Golden ratio is too far. | |
| _triangle_path_u = Path._create_closed([[0, 1], [-3/5, -1/5], [3/5, -1/5]]) | |
| _triangle_path_d = Path._create_closed( | |
| [[-3/5, -1/5], [3/5, -1/5], [1, -1], [-1, -1]]) | |
| _triangle_path_l = Path._create_closed([[0, 1], [0, -1], [-1, -1]]) | |
| _triangle_path_r = Path._create_closed([[0, 1], [0, -1], [1, -1]]) | |
| def _set_triangle(self, rot, skip): | |
| self._transform = Affine2D().scale(0.5).rotate_deg(rot) | |
| self._snap_threshold = 5.0 | |
| if not self._half_fill(): | |
| self._path = self._triangle_path | |
| else: | |
| mpaths = [self._triangle_path_u, | |
| self._triangle_path_l, | |
| self._triangle_path_d, | |
| self._triangle_path_r] | |
| fs = self.get_fillstyle() | |
| if fs == 'top': | |
| self._path = mpaths[(0 + skip) % 4] | |
| self._alt_path = mpaths[(2 + skip) % 4] | |
| elif fs == 'bottom': | |
| self._path = mpaths[(2 + skip) % 4] | |
| self._alt_path = mpaths[(0 + skip) % 4] | |
| elif fs == 'left': | |
| self._path = mpaths[(1 + skip) % 4] | |
| self._alt_path = mpaths[(3 + skip) % 4] | |
| else: | |
| self._path = mpaths[(3 + skip) % 4] | |
| self._alt_path = mpaths[(1 + skip) % 4] | |
| self._alt_transform = self._transform | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| def _set_triangle_up(self): | |
| return self._set_triangle(0.0, 0) | |
| def _set_triangle_down(self): | |
| return self._set_triangle(180.0, 2) | |
| def _set_triangle_left(self): | |
| return self._set_triangle(90.0, 3) | |
| def _set_triangle_right(self): | |
| return self._set_triangle(270.0, 1) | |
| def _set_square(self): | |
| self._transform = Affine2D().translate(-0.5, -0.5) | |
| self._snap_threshold = 2.0 | |
| if not self._half_fill(): | |
| self._path = Path.unit_rectangle() | |
| else: | |
| # Build a bottom filled square out of two rectangles, one filled. | |
| self._path = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 0.5], | |
| [0.0, 0.5], [0.0, 0.0]]) | |
| self._alt_path = Path([[0.0, 0.5], [1.0, 0.5], [1.0, 1.0], | |
| [0.0, 1.0], [0.0, 0.5]]) | |
| fs = self.get_fillstyle() | |
| rotate = {'bottom': 0, 'right': 90, 'top': 180, 'left': 270}[fs] | |
| self._transform.rotate_deg(rotate) | |
| self._alt_transform = self._transform | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| def _set_diamond(self): | |
| self._transform = Affine2D().translate(-0.5, -0.5).rotate_deg(45) | |
| self._snap_threshold = 5.0 | |
| if not self._half_fill(): | |
| self._path = Path.unit_rectangle() | |
| else: | |
| self._path = Path([[0, 0], [1, 0], [1, 1], [0, 0]]) | |
| self._alt_path = Path([[0, 0], [0, 1], [1, 1], [0, 0]]) | |
| fs = self.get_fillstyle() | |
| rotate = {'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs] | |
| self._transform.rotate_deg(rotate) | |
| self._alt_transform = self._transform | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| def _set_thin_diamond(self): | |
| self._set_diamond() | |
| self._transform.scale(0.6, 1.0) | |
| def _set_pentagon(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = 5.0 | |
| polypath = Path.unit_regular_polygon(5) | |
| if not self._half_fill(): | |
| self._path = polypath | |
| else: | |
| verts = polypath.vertices | |
| y = (1 + np.sqrt(5)) / 4. | |
| top = Path(verts[[0, 1, 4, 0]]) | |
| bottom = Path(verts[[1, 2, 3, 4, 1]]) | |
| left = Path([verts[0], verts[1], verts[2], [0, -y], verts[0]]) | |
| right = Path([verts[0], verts[4], verts[3], [0, -y], verts[0]]) | |
| self._path, self._alt_path = { | |
| 'top': (top, bottom), 'bottom': (bottom, top), | |
| 'left': (left, right), 'right': (right, left), | |
| }[self.get_fillstyle()] | |
| self._alt_transform = self._transform | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| def _set_star(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = 5.0 | |
| polypath = Path.unit_regular_star(5, innerCircle=0.381966) | |
| if not self._half_fill(): | |
| self._path = polypath | |
| else: | |
| verts = polypath.vertices | |
| top = Path(np.concatenate([verts[0:4], verts[7:10], verts[0:1]])) | |
| bottom = Path(np.concatenate([verts[3:8], verts[3:4]])) | |
| left = Path(np.concatenate([verts[0:6], verts[0:1]])) | |
| right = Path(np.concatenate([verts[0:1], verts[5:10], verts[0:1]])) | |
| self._path, self._alt_path = { | |
| 'top': (top, bottom), 'bottom': (bottom, top), | |
| 'left': (left, right), 'right': (right, left), | |
| }[self.get_fillstyle()] | |
| self._alt_transform = self._transform | |
| self._joinstyle = self._user_joinstyle or JoinStyle.bevel | |
| def _set_hexagon1(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = None | |
| polypath = Path.unit_regular_polygon(6) | |
| if not self._half_fill(): | |
| self._path = polypath | |
| else: | |
| verts = polypath.vertices | |
| # not drawing inside lines | |
| x = np.abs(np.cos(5 * np.pi / 6.)) | |
| top = Path(np.concatenate([[(-x, 0)], verts[[1, 0, 5]], [(x, 0)]])) | |
| bottom = Path(np.concatenate([[(-x, 0)], verts[2:5], [(x, 0)]])) | |
| left = Path(verts[0:4]) | |
| right = Path(verts[[0, 5, 4, 3]]) | |
| self._path, self._alt_path = { | |
| 'top': (top, bottom), 'bottom': (bottom, top), | |
| 'left': (left, right), 'right': (right, left), | |
| }[self.get_fillstyle()] | |
| self._alt_transform = self._transform | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| def _set_hexagon2(self): | |
| self._transform = Affine2D().scale(0.5).rotate_deg(30) | |
| self._snap_threshold = None | |
| polypath = Path.unit_regular_polygon(6) | |
| if not self._half_fill(): | |
| self._path = polypath | |
| else: | |
| verts = polypath.vertices | |
| # not drawing inside lines | |
| x, y = np.sqrt(3) / 4, 3 / 4. | |
| top = Path(verts[[1, 0, 5, 4, 1]]) | |
| bottom = Path(verts[1:5]) | |
| left = Path(np.concatenate([ | |
| [(x, y)], verts[:3], [(-x, -y), (x, y)]])) | |
| right = Path(np.concatenate([ | |
| [(x, y)], verts[5:2:-1], [(-x, -y)]])) | |
| self._path, self._alt_path = { | |
| 'top': (top, bottom), 'bottom': (bottom, top), | |
| 'left': (left, right), 'right': (right, left), | |
| }[self.get_fillstyle()] | |
| self._alt_transform = self._transform | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| def _set_octagon(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = 5.0 | |
| polypath = Path.unit_regular_polygon(8) | |
| if not self._half_fill(): | |
| self._transform.rotate_deg(22.5) | |
| self._path = polypath | |
| else: | |
| x = np.sqrt(2.) / 4. | |
| self._path = self._alt_path = Path( | |
| [[0, -1], [0, 1], [-x, 1], [-1, x], | |
| [-1, -x], [-x, -1], [0, -1]]) | |
| fs = self.get_fillstyle() | |
| self._transform.rotate_deg( | |
| {'left': 0, 'bottom': 90, 'right': 180, 'top': 270}[fs]) | |
| self._alt_transform = self._transform.frozen().rotate_deg(180.0) | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]]) | |
| def _set_vline(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = 1.0 | |
| self._filled = False | |
| self._path = self._line_marker_path | |
| def _set_hline(self): | |
| self._set_vline() | |
| self._transform = self._transform.rotate_deg(90) | |
| _tickhoriz_path = Path([[0.0, 0.0], [1.0, 0.0]]) | |
| def _set_tickleft(self): | |
| self._transform = Affine2D().scale(-1.0, 1.0) | |
| self._snap_threshold = 1.0 | |
| self._filled = False | |
| self._path = self._tickhoriz_path | |
| def _set_tickright(self): | |
| self._transform = Affine2D().scale(1.0, 1.0) | |
| self._snap_threshold = 1.0 | |
| self._filled = False | |
| self._path = self._tickhoriz_path | |
| _tickvert_path = Path([[-0.0, 0.0], [-0.0, 1.0]]) | |
| def _set_tickup(self): | |
| self._transform = Affine2D().scale(1.0, 1.0) | |
| self._snap_threshold = 1.0 | |
| self._filled = False | |
| self._path = self._tickvert_path | |
| def _set_tickdown(self): | |
| self._transform = Affine2D().scale(1.0, -1.0) | |
| self._snap_threshold = 1.0 | |
| self._filled = False | |
| self._path = self._tickvert_path | |
| _tri_path = Path([[0.0, 0.0], [0.0, -1.0], | |
| [0.0, 0.0], [0.8, 0.5], | |
| [0.0, 0.0], [-0.8, 0.5]], | |
| [Path.MOVETO, Path.LINETO, | |
| Path.MOVETO, Path.LINETO, | |
| Path.MOVETO, Path.LINETO]) | |
| def _set_tri_down(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = 5.0 | |
| self._filled = False | |
| self._path = self._tri_path | |
| def _set_tri_up(self): | |
| self._set_tri_down() | |
| self._transform = self._transform.rotate_deg(180) | |
| def _set_tri_left(self): | |
| self._set_tri_down() | |
| self._transform = self._transform.rotate_deg(270) | |
| def _set_tri_right(self): | |
| self._set_tri_down() | |
| self._transform = self._transform.rotate_deg(90) | |
| _caret_path = Path([[-1.0, 1.5], [0.0, 0.0], [1.0, 1.5]]) | |
| def _set_caretdown(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = 3.0 | |
| self._filled = False | |
| self._path = self._caret_path | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| def _set_caretup(self): | |
| self._set_caretdown() | |
| self._transform = self._transform.rotate_deg(180) | |
| def _set_caretleft(self): | |
| self._set_caretdown() | |
| self._transform = self._transform.rotate_deg(270) | |
| def _set_caretright(self): | |
| self._set_caretdown() | |
| self._transform = self._transform.rotate_deg(90) | |
| _caret_path_base = Path([[-1.0, 0.0], [0.0, -1.5], [1.0, 0]]) | |
| def _set_caretdownbase(self): | |
| self._set_caretdown() | |
| self._path = self._caret_path_base | |
| def _set_caretupbase(self): | |
| self._set_caretdownbase() | |
| self._transform = self._transform.rotate_deg(180) | |
| def _set_caretleftbase(self): | |
| self._set_caretdownbase() | |
| self._transform = self._transform.rotate_deg(270) | |
| def _set_caretrightbase(self): | |
| self._set_caretdownbase() | |
| self._transform = self._transform.rotate_deg(90) | |
| _plus_path = Path([[-1.0, 0.0], [1.0, 0.0], | |
| [0.0, -1.0], [0.0, 1.0]], | |
| [Path.MOVETO, Path.LINETO, | |
| Path.MOVETO, Path.LINETO]) | |
| def _set_plus(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = 1.0 | |
| self._filled = False | |
| self._path = self._plus_path | |
| _x_path = Path([[-1.0, -1.0], [1.0, 1.0], | |
| [-1.0, 1.0], [1.0, -1.0]], | |
| [Path.MOVETO, Path.LINETO, | |
| Path.MOVETO, Path.LINETO]) | |
| def _set_x(self): | |
| self._transform = Affine2D().scale(0.5) | |
| self._snap_threshold = 3.0 | |
| self._filled = False | |
| self._path = self._x_path | |
| _plus_filled_path = Path._create_closed(np.array([ | |
| (-1, -3), (+1, -3), (+1, -1), (+3, -1), (+3, +1), (+1, +1), | |
| (+1, +3), (-1, +3), (-1, +1), (-3, +1), (-3, -1), (-1, -1)]) / 6) | |
| _plus_filled_path_t = Path._create_closed(np.array([ | |
| (+3, 0), (+3, +1), (+1, +1), (+1, +3), | |
| (-1, +3), (-1, +1), (-3, +1), (-3, 0)]) / 6) | |
| def _set_plus_filled(self): | |
| self._transform = Affine2D() | |
| self._snap_threshold = 5.0 | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| if not self._half_fill(): | |
| self._path = self._plus_filled_path | |
| else: | |
| # Rotate top half path to support all partitions | |
| self._path = self._alt_path = self._plus_filled_path_t | |
| fs = self.get_fillstyle() | |
| self._transform.rotate_deg( | |
| {'top': 0, 'left': 90, 'bottom': 180, 'right': 270}[fs]) | |
| self._alt_transform = self._transform.frozen().rotate_deg(180) | |
| _x_filled_path = Path._create_closed(np.array([ | |
| (-1, -2), (0, -1), (+1, -2), (+2, -1), (+1, 0), (+2, +1), | |
| (+1, +2), (0, +1), (-1, +2), (-2, +1), (-1, 0), (-2, -1)]) / 4) | |
| _x_filled_path_t = Path._create_closed(np.array([ | |
| (+1, 0), (+2, +1), (+1, +2), (0, +1), | |
| (-1, +2), (-2, +1), (-1, 0)]) / 4) | |
| def _set_x_filled(self): | |
| self._transform = Affine2D() | |
| self._snap_threshold = 5.0 | |
| self._joinstyle = self._user_joinstyle or JoinStyle.miter | |
| if not self._half_fill(): | |
| self._path = self._x_filled_path | |
| else: | |
| # Rotate top half path to support all partitions | |
| self._path = self._alt_path = self._x_filled_path_t | |
| fs = self.get_fillstyle() | |
| self._transform.rotate_deg( | |
| {'top': 0, 'left': 90, 'bottom': 180, 'right': 270}[fs]) | |
| self._alt_transform = self._transform.frozen().rotate_deg(180) | |
Xet Storage Details
- Size:
- 33.7 kB
- Xet hash:
- efe46fc47b1d23084a073b35b62cb2df02921fd24d971c9de8d57421c0e0006e
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.