Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Rework quiver's color-setting API #13423

Copy link
Copy link
Open
@anntzer

Description

@anntzer
Issue body actions

quiver's docs currently read

    Call signatures::
    
      quiver(U, V, **kw)
      quiver(U, V, C, **kw)
      quiver(X, Y, U, V, **kw)
      quiver(X, Y, U, V, C, **kw)
    
    *U* and *V* are the arrow data, *X* and *Y* set the location of the
    arrows, and *C* sets the color of the arrows. These arguments may be 1-D or
    2-D arrays or sequences.

    ...

    Parameters
    ----------
    X : 1D or 2D array, sequence, optional
        The x coordinates of the arrow locations
    Y : 1D or 2D array, sequence, optional
        The y coordinates of the arrow locations
    U : 1D or 2D array or masked array, sequence
        The x components of the arrow vectors
    V : 1D or 2D array or masked array, sequence
        The y components of the arrow vectors
    C : 1D or 2D array, sequence, optional
        The arrow colors

OK, let's try to draw 4 arrows, each with u=v=1, in red (1, 0, 0), green (0, 1, 0), blue (0, 0, 1), and gray (.5, .5, .5)

quiver([1, 1, 1, 1], [1, 1, 1, 1], ["r", "g", "b", "gray"])
...
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Oops. Let's try to pass in RGB color tuples instead? (in the same format as scatter would take them)

quiver([1, 1, 1, 1], [1, 1, 1, 1], [[1, 0, 0], [0, 1, 0], [0, 0, 1], [.5, .5, .5]])

bad
??
To cut a long story short: this took the first 4 values in the flattened color array (1, 0, 0, 0) and colormapped them using the default colormap.

Actually, the correct solution to set the colors is to read all the way to the end of the docstring and notice

    color : [ color | color sequence ], optional
        This is a synonym for the
        :class:`~matplotlib.collections.PolyCollection` facecolor kwarg.
        If *C* has been set, *color* has no effect.

Indeed

quiver([1, 1, 1, 1], [1, 1, 1, 1], color=["r", "g", "b", "gray"])

or

quiver([1, 1, 1, 1], [1, 1, 1, 1], color=[[1, 0, 0], [0, 1, 0], [0, 0, 1], [.5, .5, .5]])

both work:
good

I think this API is clearly... not optimal.

I propose to instead make C check its shape; if its shape is (*X.shape, 3) or (*X.shape, 4), then treat it as RGB; if its shape is X.shape, treat it as colormapped values; otherwise, error out (and for consistency, check that the shapes of X, Y, U, V all match (instead of flattening them all)).

I'm not sure the behavior change needs a deprecation period (it would only affect people purposefully passing three or four times to many values as the C array as the rest would currently be ignored); obviously there would be a deprecation during which non-matching X, Y, U, V would warn instead of error out.

The color arg could also be deprecated, as it is now a complete synonym for C. Alternatively, we could instead deprecate C in favor of color, which would have the benefit of making the signatures a bit nicer (now it's just quiver(U, V, **kwargs) and quiver(X, Y, U, V, **kwargs)) but is perhaps mildly more disruptive.

Thoughts?

This is as of mpl 3.0.x.

Metadata

Metadata

Assignees

No one assigned

    Labels

    API: consistencykeepItems to be ignored by the “Stale” Github ActionItems to be ignored by the “Stale” Github Action

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.