Esempio n. 1
0
    def update(self, data):
        """
        Map new values to integer identifiers.

        Parameters
        ----------
        data : iterable of str or bytes

        Raises
        ------
        TypeError
            If elements in *data* are neither str nor bytes.
        """
        data = np.atleast_1d(np.array(data, dtype=object))
        # check if convertible to number:
        convertible = True
        for val in OrderedDict.fromkeys(data):
            # OrderedDict just iterates over unique values in data.
            _api.check_isinstance((str, bytes), value=val)
            if convertible:
                # this will only be called so long as convertible is True.
                convertible = self._str_is_convertible(val)
            if val not in self._mapping:
                self._mapping[val] = next(self._counter)
        if convertible:
            _log.info('Using categorical units to plot a list of strings '
                      'that are all parsable as floats or dates. If these '
                      'strings should be plotted as numbers, cast to the '
                      'appropriate data type before plotting.')
Esempio n. 2
0
def register_cmap(name=None, cmap=None, *, override_builtin=False):
    """
    Add a colormap to the set recognized by :func:`get_cmap`.

    Register a new colormap to be accessed by name ::

        LinearSegmentedColormap('swirly', data, lut)
        register_cmap(cmap=swirly_cmap)

    Parameters
    ----------
    name : str, optional
       The name that can be used in :func:`get_cmap` or :rc:`image.cmap`

       If absent, the name will be the :attr:`~matplotlib.colors.Colormap.name`
       attribute of the *cmap*.

    cmap : matplotlib.colors.Colormap
       Despite being the second argument and having a default value, this
       is a required argument.

    override_builtin : bool

        Allow built-in colormaps to be overridden by a user-supplied
        colormap.

        Please do not use this unless you are sure you need it.

    Notes
    -----
    Registering a colormap stores a reference to the colormap object
    which can currently be modified and inadvertently change the global
    colormap state. This behavior is deprecated and in Matplotlib 3.5
    the registered colormap will be immutable.

    """
    _api.check_isinstance((str, None), name=name)
    if name is None:
        try:
            name = cmap.name
        except AttributeError as err:
            raise ValueError("Arguments must include a name or a "
                             "Colormap") from err
    if name in _cmap_registry:
        if not override_builtin and name in __builtin_cmaps:
            msg = f"Trying to re-register the builtin cmap {name!r}."
            raise ValueError(msg)
        else:
            msg = f"Trying to register the cmap {name!r} which already exists."
            _api.warn_external(msg)

    if not isinstance(cmap, colors.Colormap):
        raise ValueError("You must pass a Colormap instance. "
                         f"You passed {cmap} a {type(cmap)} object.")

    cmap._global = True
    _cmap_registry[name] = cmap
    return
Esempio n. 3
0
 def __init__(self, scale, tfm, texname, vf):
     _api.check_isinstance(bytes, texname=texname)
     self._scale = scale
     self._tfm = tfm
     self.texname = texname
     self._vf = vf
     self.size = scale * (72.0 / (72.27 * 2**16))
     try:
         nchars = max(tfm.width) + 1
     except ValueError:
         nchars = 0
     self.widths = [(1000 * tfm.width.get(char, 0)) >> 20
                    for char in range(nchars)]
Esempio n. 4
0
def validate_hatch(s):
    r"""
    Validate a hatch pattern.
    A hatch pattern string can have any sequence of the following
    characters: ``\ / | - + * . x o O``.
    """
    if not isinstance(s, str):
        raise ValueError("Hatch pattern must be a string")
    _api.check_isinstance(str, hatch_pattern=s)
    unknown = set(s) - {'\\', '/', '|', '-', '+', '*', '.', 'x', 'o', 'O'}
    if unknown:
        raise ValueError("Unknown hatch symbol(s): %s" % list(unknown))
    return s
Esempio n. 5
0
    def __init__(self, axes, spine_type, path, **kwargs):
        """
        Parameters
        ----------
        axes : `~matplotlib.axes.Axes`
            The `~.axes.Axes` instance containing the spine.
        spine_type : str
            The spine type.
        path : `~matplotlib.path.Path`
            The `.Path` instance used to draw the spine.

        Other Parameters
        ----------------
        **kwargs
            Valid keyword arguments are:

            %(Patch:kwdoc)s
        """
        super().__init__(**kwargs)
        self.axes = axes
        self.set_figure(self.axes.figure)
        self.spine_type = spine_type
        self.set_facecolor('none')
        self.set_edgecolor(rcParams['axes.edgecolor'])
        self.set_linewidth(rcParams['axes.linewidth'])
        self.set_capstyle('projecting')
        self.axis = None

        self.set_zorder(2.5)
        self.set_transform(self.axes.transData)  # default transform

        self._bounds = None  # default bounds

        # Defer initial position determination. (Not much support for
        # non-rectangular axes is currently implemented, and this lets
        # them pass through the spines machinery without errors.)
        self._position = None
        _api.check_isinstance(matplotlib.path.Path, path=path)
        self._path = path

        # To support drawing both linear and circular spines, this
        # class implements Patch behavior three ways. If
        # self._patch_type == 'line', behave like a mpatches.PathPatch
        # instance. If self._patch_type == 'circle', behave like a
        # mpatches.Ellipse instance. If self._patch_type == 'arc', behave like
        # a mpatches.Arc instance.
        self._patch_type = 'line'

        # Behavior copied from mpatches.Ellipse:
        # Note: This cannot be calculated until this is added to an Axes
        self._patch_transform = mtransforms.IdentityTransform()
Esempio n. 6
0
    def norm(self, norm):
        _api.check_isinstance((colors.Normalize, None), norm=norm)
        if norm is None:
            norm = colors.Normalize()

        if norm is self.norm:
            # We aren't updating anything
            return

        in_init = self.norm is None
        # Remove the current callback and connect to the new one
        if not in_init:
            self.norm.callbacks.disconnect(self._id_norm)
        self._norm = norm
        self._id_norm = self.norm.callbacks.connect('changed', self.changed)
        if not in_init:
            self.changed()
Esempio n. 7
0
    def register(self, cmap, *, name=None, force=False):
        """
        Register a new colormap.

        The colormap name can then be used as a string argument to any ``cmap``
        parameter in Matplotlib. It is also available in ``pyplot.get_cmap``.

        The colormap registry stores a copy of the given colormap, so that
        future changes to the original colormap instance do not affect the
        registered colormap. Think of this as the registry taking a snapshot
        of the colormap at registration.

        Parameters
        ----------
        cmap : matplotlib.colors.Colormap
            The colormap to register.

        name : str, optional
            The name for the colormap. If not given, ``cmap.name`` is used.

        force : bool, default: False
            If False, a ValueError is raised if trying to overwrite an already
            registered name. True supports overwriting registered colormaps
            other than the builtin colormaps.
        """
        _api.check_isinstance(colors.Colormap, cmap=cmap)

        name = name or cmap.name
        if name in self:
            if not force:
                # don't allow registering an already existing cmap
                # unless explicitly asked to
                raise ValueError(
                    f'A colormap named "{name}" is already registered.')
            elif (name in self._builtin_cmaps
                    and not self._allow_override_builtin):
                # We don't allow overriding a builtin unless privately
                # coming from register_cmap()
                raise ValueError("Re-registering the builtin cmap "
                                 f"{name!r} is not allowed.")

            # Warn that we are updating an already existing colormap
            _api.warn_external(f"Overwriting the cmap {name!r} "
                               "that was already in the registry.")

        self._cmaps[name] = cmap.copy()
Esempio n. 8
0
    def __call__(self, n=1, timeout=30):
        """Blocking call to retrieve *n* events."""
        _api.check_isinstance(Integral, n=n)
        self.n = n
        self.events = []

        if hasattr(self.fig.canvas, "manager"):
            # Ensure that the figure is shown, if we are managing it.
            self.fig.show()
        # Connect the events to the on_event function call.
        self.callbacks = [self.fig.canvas.mpl_connect(name, self.on_event)
                          for name in self.eventslist]
        try:
            # Start event loop.
            self.fig.canvas.start_event_loop(timeout=timeout)
        finally:  # Run even on exception like ctrl-c.
            # Disconnect the callbacks.
            self.cleanup()
        # Return the events in this case.
        return self.events
Esempio n. 9
0
def register_cmap(name=None, cmap=None, *, override_builtin=False):
    """
    Add a colormap to the set recognized by :func:`get_cmap`.

    Register a new colormap to be accessed by name ::

        LinearSegmentedColormap('swirly', data, lut)
        register_cmap(cmap=swirly_cmap)

    Parameters
    ----------
    name : str, optional
       The name that can be used in :func:`get_cmap` or :rc:`image.cmap`

       If absent, the name will be the :attr:`~matplotlib.colors.Colormap.name`
       attribute of the *cmap*.

    cmap : matplotlib.colors.Colormap
       Despite being the second argument and having a default value, this
       is a required argument.

    override_builtin : bool

        Allow built-in colormaps to be overridden by a user-supplied
        colormap.

        Please do not use this unless you are sure you need it.
    """
    _api.check_isinstance((str, None), name=name)
    if name is None:
        try:
            name = cmap.name
        except AttributeError as err:
            raise ValueError("Arguments must include a name or a "
                             "Colormap") from err
    # override_builtin is allowed here for backward compatibility
    # this is just a shim to enable that to work privately in
    # the global ColormapRegistry
    _colormaps._allow_override_builtin = override_builtin
    _colormaps.register(cmap, name=name, force=override_builtin)
    _colormaps._allow_override_builtin = False
Esempio n. 10
0
    def set_norm(self, norm):
        """
        Set the normalization instance.

        Parameters
        ----------
        norm : `.Normalize` or None

        Notes
        -----
        If there are any colorbars using the mappable for this norm, setting
        the norm of the mappable will reset the norm, locator, and formatters
        on the colorbar to default.
        """
        _api.check_isinstance((colors.Normalize, None), norm=norm)
        in_init = self.norm is None
        if norm is None:
            norm = colors.Normalize()
        self.norm = norm
        if not in_init:
            self.changed()  # Things are not set up properly yet.
Esempio n. 11
0
    def refine_field(self, z, triinterpolator=None, subdiv=3):
        """
        Refine a field defined on the encapsulated triangulation.

        Parameters
        ----------
        z : array-like of length ``n_points``
            Values of the field to refine, defined at the nodes of the
            encapsulated triangulation. (``n_points`` is the number of points
            in the initial triangulation)
        triinterpolator : `~matplotlib.tri.TriInterpolator`, optional
            Interpolator used for field interpolation. If not specified,
            a `~matplotlib.tri.CubicTriInterpolator` will be used.
        subdiv : int, default: 3
            Recursion level for the subdivision.
            Each triangle is divided into ``4**subdiv`` child triangles.

        Returns
        -------
        refi_tri : `~matplotlib.tri.Triangulation`
             The returned refined triangulation.
        refi_z : 1D array of length: *refi_tri* node count.
             The returned interpolated field (at *refi_tri* nodes).
        """
        if triinterpolator is None:
            interp = matplotlib.tri.CubicTriInterpolator(
                self._triangulation, z)
        else:
            _api.check_isinstance(matplotlib.tri.TriInterpolator,
                                  triinterpolator=triinterpolator)
            interp = triinterpolator

        refi_tri, found_index = self.refine_triangulation(
            subdiv=subdiv, return_tri_index=True)
        refi_z = interp._interpolate_multikeys(refi_tri.x,
                                               refi_tri.y,
                                               tri_index=found_index)[0]
        return refi_tri, refi_z
Esempio n. 12
0
 def __init__(self, triangulation):
     _api.check_isinstance(Triangulation, triangulation=triangulation)
     self._triangulation = triangulation
Esempio n. 13
0
def _validate_cmap(s):
    _api.check_isinstance((str, Colormap), cmap=s)
    return s
Esempio n. 14
0
def tripcolor(ax,
              *args,
              alpha=1.0,
              norm=None,
              cmap=None,
              vmin=None,
              vmax=None,
              shading='flat',
              facecolors=None,
              **kwargs):
    """
    Create a pseudocolor plot of an unstructured triangular grid.

    Call signatures::

      tripcolor(triangulation, C, *, ...)
      tripcolor(x, y, C, *, [triangles=triangles], [mask=mask], ...)

    The triangular grid can be specified either by passing a `.Triangulation`
    object as the first parameter, or by passing the points *x*, *y* and
    optionally the *triangles* and a *mask*. See `.Triangulation` for an
    explanation of these parameters.

    If neither of *triangulation* or *triangles* are given, the triangulation
    is calculated on the fly. In this case, it does not make sense to provide
    colors at the triangle faces via *C* or *facecolors* because there are
    multiple possible triangulations for a group of points and you don't know
    which triangles will be constructed.

    Parameters
    ----------
    triangulation : `.Triangulation`
        An already created triangular grid.
    x, y, triangles, mask
        Parameters defining the triangular grid. See `.Triangulation`.
        This is mutually exclusive with specifying *triangulation*.
    C : array-like
        The color values, either for the points or for the triangles. Which one
        is automatically inferred from the length of *C*, i.e. does it match
        the number of points or the number of triangles. If there are the same
        number of points and triangles in the triangulation it is assumed that
        color values are defined at points; to force the use of color values at
        triangles use the keyword argument ``facecolors=C`` instead of just
        ``C``.
        This parameter is position-only.
    facecolors : array-like, optional
        Can be used alternatively to *C* to specify colors at the triangle
        faces. This parameter takes precedence over *C*.
    shading : {'flat', 'gouraud'}, default: 'flat'
        If  'flat' and the color values *C* are defined at points, the color
        values used for each triangle are from the mean C of the triangle's
        three points. If *shading* is 'gouraud' then color values must be
        defined at points.
    other_parameters
        All other parameters are the same as for `~.Axes.pcolor`.

    Notes
    -----
    It is possible to pass the triangles positionally, i.e.
    ``tripcolor(x, y, triangles, C, ...)``. However, this is discouraged.
    For more clarity, pass *triangles* via keyword argument.
    """
    _api.check_in_list(['flat', 'gouraud'], shading=shading)

    tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)

    # Parse the color to be in one of (the other variable will be None):
    # - facecolors: if specified at the triangle faces
    # - point_colors: if specified at the points
    if facecolors is not None:
        if args:
            _api.warn_external(
                "Positional parameter C has no effect when the keyword "
                "facecolors is given")
        point_colors = None
        if len(facecolors) != len(tri.triangles):
            raise ValueError("The length of facecolors must match the number "
                             "of triangles")
    else:
        # Color from positional parameter C
        if not args:
            raise ValueError(
                "Missing color parameter. Please pass C positionally or "
                "facecolors via keyword")
        elif len(args) > 1:
            _api.warn_external(
                "Additional positional parameters {args[1:]!r} are ignored")
        C = np.asarray(args[0])
        if len(C) == len(tri.x):
            # having this before the len(tri.triangles) comparison gives
            # precedence to nodes if there are as many nodes as triangles
            point_colors = C
            facecolors = None
        elif len(C) == len(tri.triangles):
            point_colors = None
            facecolors = C
        else:
            raise ValueError('The length of C must match either the number '
                             'of points or the number of triangles')

    # Handling of linewidths, shading, edgecolors and antialiased as
    # in Axes.pcolor
    linewidths = (0.25, )
    if 'linewidth' in kwargs:
        kwargs['linewidths'] = kwargs.pop('linewidth')
    kwargs.setdefault('linewidths', linewidths)

    edgecolors = 'none'
    if 'edgecolor' in kwargs:
        kwargs['edgecolors'] = kwargs.pop('edgecolor')
    ec = kwargs.setdefault('edgecolors', edgecolors)

    if 'antialiased' in kwargs:
        kwargs['antialiaseds'] = kwargs.pop('antialiased')
    if 'antialiaseds' not in kwargs and ec.lower() == "none":
        kwargs['antialiaseds'] = False

    _api.check_isinstance((Normalize, None), norm=norm)
    if shading == 'gouraud':
        if facecolors is not None:
            raise ValueError(
                "shading='gouraud' can only be used when the colors "
                "are specified at the points, not at the faces.")
        collection = TriMesh(tri,
                             alpha=alpha,
                             array=point_colors,
                             cmap=cmap,
                             norm=norm,
                             **kwargs)
    else:
        # Vertices of triangles.
        maskedTris = tri.get_masked_triangles()
        verts = np.stack((tri.x[maskedTris], tri.y[maskedTris]), axis=-1)

        # Color values.
        if facecolors is None:
            # One color per triangle, the mean of the 3 vertex color values.
            colors = point_colors[maskedTris].mean(axis=1)
        elif tri.mask is not None:
            # Remove color values of masked triangles.
            colors = facecolors[~tri.mask]
        else:
            colors = facecolors
        collection = PolyCollection(verts,
                                    alpha=alpha,
                                    array=colors,
                                    cmap=cmap,
                                    norm=norm,
                                    **kwargs)

    collection._scale_norm(norm, vmin, vmax)
    ax.grid(False)

    minx = tri.x.min()
    maxx = tri.x.max()
    miny = tri.y.min()
    maxy = tri.y.max()
    corners = (minx, miny), (maxx, maxy)
    ax.update_datalim(corners)
    ax.autoscale_view()
    ax.add_collection(collection)
    return collection
Esempio n. 15
0
 def __init__(self, fraction, ref_size):
     _api.check_isinstance(Number, fraction=fraction)
     self._fraction_ref = ref_size
     self._fraction = fraction
Esempio n. 16
0
 def __init__(self, *args, grid_helper, **kwargs):
     _api.check_isinstance(GridHelperCurveLinear, grid_helper=grid_helper)
     super().__init__(*args, grid_helper=grid_helper, **kwargs)
     self.set_aspect(1.)
     self.adjust_axes_lim()
Esempio n. 17
0
def tripcolor(ax,
              *args,
              alpha=1.0,
              norm=None,
              cmap=None,
              vmin=None,
              vmax=None,
              shading='flat',
              facecolors=None,
              **kwargs):
    """
    Create a pseudocolor plot of an unstructured triangular grid.

    The triangulation can be specified in one of two ways; either::

      tripcolor(triangulation, ...)

    where triangulation is a `.Triangulation` object, or

    ::

      tripcolor(x, y, ...)
      tripcolor(x, y, triangles, ...)
      tripcolor(x, y, triangles=triangles, ...)
      tripcolor(x, y, mask=mask, ...)
      tripcolor(x, y, triangles, mask=mask, ...)

    in which case a Triangulation object will be created.  See `.Triangulation`
    for a explanation of these possibilities.

    The next argument must be *C*, the array of color values, either
    one per point in the triangulation if color values are defined at
    points, or one per triangle in the triangulation if color values
    are defined at triangles. If there are the same number of points
    and triangles in the triangulation it is assumed that color
    values are defined at points; to force the use of color values at
    triangles use the kwarg ``facecolors=C`` instead of just ``C``.

    *shading* may be 'flat' (the default) or 'gouraud'. If *shading*
    is 'flat' and C values are defined at points, the color values
    used for each triangle are from the mean C of the triangle's
    three points. If *shading* is 'gouraud' then color values must be
    defined at points.

    The remaining kwargs are the same as for `~.Axes.pcolor`.
    """
    _api.check_in_list(['flat', 'gouraud'], shading=shading)

    tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)

    # C is the colors array defined at either points or faces (i.e. triangles).
    # If facecolors is None, C are defined at points.
    # If facecolors is not None, C are defined at faces.
    if facecolors is not None:
        C = facecolors
    else:
        C = np.asarray(args[0])

    # If there are a different number of points and triangles in the
    # triangulation, can omit facecolors kwarg as it is obvious from
    # length of C whether it refers to points or faces.
    # Do not do this for gouraud shading.
    if (facecolors is None and len(C) == len(tri.triangles)
            and len(C) != len(tri.x) and shading != 'gouraud'):
        facecolors = C

    # Check length of C is OK.
    if ((facecolors is None and len(C) != len(tri.x))
            or (facecolors is not None and len(C) != len(tri.triangles))):
        raise ValueError('Length of color values array must be the same '
                         'as either the number of triangulation points '
                         'or triangles')

    # Handling of linewidths, shading, edgecolors and antialiased as
    # in Axes.pcolor
    linewidths = (0.25, )
    if 'linewidth' in kwargs:
        kwargs['linewidths'] = kwargs.pop('linewidth')
    kwargs.setdefault('linewidths', linewidths)

    edgecolors = 'none'
    if 'edgecolor' in kwargs:
        kwargs['edgecolors'] = kwargs.pop('edgecolor')
    ec = kwargs.setdefault('edgecolors', edgecolors)

    if 'antialiased' in kwargs:
        kwargs['antialiaseds'] = kwargs.pop('antialiased')
    if 'antialiaseds' not in kwargs and ec.lower() == "none":
        kwargs['antialiaseds'] = False

    if shading == 'gouraud':
        if facecolors is not None:
            raise ValueError('Gouraud shading does not support the use '
                             'of facecolors kwarg')
        if len(C) != len(tri.x):
            raise ValueError('For gouraud shading, the length of color '
                             'values array must be the same as the '
                             'number of triangulation points')
        collection = TriMesh(tri, **kwargs)
    else:
        # Vertices of triangles.
        maskedTris = tri.get_masked_triangles()
        verts = np.stack((tri.x[maskedTris], tri.y[maskedTris]), axis=-1)

        # Color values.
        if facecolors is None:
            # One color per triangle, the mean of the 3 vertex color values.
            C = C[maskedTris].mean(axis=1)
        elif tri.mask is not None:
            # Remove color values of masked triangles.
            C = C[~tri.mask]

        collection = PolyCollection(verts, **kwargs)

    collection.set_alpha(alpha)
    collection.set_array(C)
    _api.check_isinstance((Normalize, None), norm=norm)
    collection.set_cmap(cmap)
    collection.set_norm(norm)
    collection._scale_norm(norm, vmin, vmax)
    ax.grid(False)

    minx = tri.x.min()
    maxx = tri.x.max()
    miny = tri.y.min()
    maxy = tri.y.max()
    corners = (minx, miny), (maxx, maxy)
    ax.update_datalim(corners)
    ax.autoscale_view()
    ax.add_collection(collection)
    return collection
Esempio n. 18
0
 def __init__(self, fixed_size):
     _api.check_isinstance(Number, fixed_size=fixed_size)
     self.fixed_size = fixed_size