Skip to content

Commit b1cd0a3

Browse files
committed
improve c kwarg checking (and error messages) in scatter
1 parent dfb8936 commit b1cd0a3

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

lib/matplotlib/axes/_axes.py

+39-8
Original file line numberDiff line numberDiff line change
@@ -3792,7 +3792,9 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
37923792
Note that *c* should not be a single numeric RGB or RGBA sequence
37933793
because that is indistinguishable from an array of values to be
37943794
colormapped. If you want to specify the same RGB or RGBA value for
3795-
all points, use a 2-D array with a single row.
3795+
all points, use a 2-D array with a single row. Otherwise, value-
3796+
matching will have precedence in case of a size matching with *x*
3797+
and *y*.
37963798
37973799
marker : `~matplotlib.markers.MarkerStyle`, optional, default: 'o'
37983800
The marker style. *marker* can be either an instance of the class
@@ -3925,29 +3927,58 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
39253927
# c is an array for mapping. The potential ambiguity
39263928
# with a sequence of 3 or 4 numbers is resolved in
39273929
# favor of mapping, not rgb or rgba.
3930+
3931+
# Convenience vars to track shape mismatch *and* conversion failures.
3932+
valid_shape = True # will be put to the test!
3933+
n_elem = 0 # used only for (some) exceptions
3934+
39283935
if c_none or co is not None:
39293936
c_array = None
39303937
else:
3931-
try:
3938+
try: # First, does 'c' look suitable for value-mapping?
39323939
c_array = np.asanyarray(c, dtype=float)
3940+
n_elem = c_array.shape[0]
39333941
if c_array.shape in xy_shape:
39343942
c = np.ma.ravel(c_array)
39353943
else:
3944+
if c_array.shape in ((3,), (4,)):
3945+
_log.warning(
3946+
"'c' kwarg looks like a **single** numeric RGB or "
3947+
"RGBA sequence, which should be avoided as value-"
3948+
"mapping will have precedence in case its length "
3949+
"matches with 'x' & 'y'. Please use a 2-D array "
3950+
"with a single row if you really want to specify "
3951+
"the same RGB or RGBA value for all points.")
39363952
# Wrong size; it must not be intended for mapping.
3953+
valid_shape = False
39373954
c_array = None
39383955
except ValueError:
39393956
# Failed to make a floating-point array; c must be color specs.
39403957
c_array = None
39413958

39423959
if c_array is None:
3943-
try:
3944-
# must be acceptable as PathCollection facecolors
3960+
try: # Then is 'c' acceptable as PathCollection facecolors?
39453961
colors = mcolors.to_rgba_array(c)
3962+
n_elem = colors.shape[0]
3963+
if colors.shape[0] not in (1, x.size, y.size):
3964+
# NB: remember that a single color is also acceptable.
3965+
valid_shape = False
3966+
raise ValueError
39463967
except ValueError:
3947-
# c not acceptable as PathCollection facecolor
3948-
raise ValueError("c of shape {} not acceptable as a color "
3949-
"sequence for x with size {}, y with size {}"
3950-
.format(c.shape, x.size, y.size))
3968+
if not valid_shape: # but at least one conversion succeeded.
3969+
raise ValueError(
3970+
"'c' kwarg has {nc} elements, which is not acceptable "
3971+
"for use with 'x' with size {xs}, 'y' with size {ys}."
3972+
.format(nc=n_elem, xs=x.size, ys=y.size)
3973+
)
3974+
# Both the mapping *and* the RGBA conversion failed: pretty
3975+
# severe failure => one may appreciate a verbose feedback.
3976+
raise ValueError(
3977+
"'c' kwarg must either be valid as mpl color(s) or "
3978+
"as numbers to be mapped to colors. "
3979+
"Here c = {}." # <- beware, could be long depending on c.
3980+
.format(c)
3981+
)
39513982
else:
39523983
colors = None # use cmap, norm after collection is created
39533984

0 commit comments

Comments
 (0)