matplotlib icon indicating copy to clipboard operation
matplotlib copied to clipboard

[Bug]: to_rgba_array("none") returns empty array

Open story645 opened this issue 1 year ago • 1 comments

Bug summary

mcolors.to_rgba_array("none") returns an empty array while mcolors.to_rgba("none") and mcolors.to_rgba_array(["none"]) return (0,0,0,0) (which is the documented value of None) and this leads to inconsistencies when trying to use mcolors.same_color

Actual outcome

>>> import matplotlib.colors as mcolors
>>> mcolors.to_rgba("none")
(0.0, 0.0, 0.0, 0.0)
>>> mcolors.to_rgba_array("none") 
array([], shape=(0, 4), dtype=float64)
>>> mcolors.to_rgba_array(["none"])
array([[0., 0., 0., 0.]])
>>> mcolors.same_color("none", mcolors.to_rgba("none"))
False
>>> mcolors.same_color(["none"], mcolors.to_rgba("none")) 
True

Expected outcome

>>> import matplotlib.colors as mcolors
>>> mcolors.to_rgba("none")
(0.0, 0.0, 0.0, 0.0)
>>> mcolors.to_rgba_array("none") 
array([[0., 0., 0., 0.]])
>>> mcolors.to_rgba_array(["none"])
array([[0., 0., 0., 0.]])
>>> mcolors.same_color("none", mcolors.to_rgba("none"))
True
>>> mcolors.same_color(["none"], mcolors.to_rgba("none")) 
True

Additional information

I tried the quick fixes of changing the return here to array([[0., 0., 0., 0.]]) and np.array([to_rgba('none')], float)

https://github.com/matplotlib/matplotlib/blob/d347c3227f8de8a99aa327390fee619310452a96/lib/matplotlib/colors.py#L482-L483

That yielded a ton of test failures, mostly around colorbars/contours, hatches, and but roughly the diffs all looked something like this:

contourf_extend_patches (actual, expected) image

colorbar_two_slope image

Also I realize this could be not worth fixing and a quick fix is to cast none to a list in same_color

story645 avatar Jun 27 '24 00:06 story645

Someone at scipy tracked this down to being an issue w/ eager conversion to color that relies on 'none'/empty array for if statements to preserve the correct alpha values. xref #28710

story645 avatar Aug 12 '24 21:08 story645

The existing behaviour is clearly deliberate but I agree with @story645 about what I expected to happen. Is it worth adding a boolean parameter so you could choose between the two behaviours?

rcomer avatar Mar 09 '25 10:03 rcomer

Is it worth adding a boolean parameter so you could choose between the two behaviours?

I've been thinking of a sort of true constant for none, but flagging would probably do the same trick - what I'm thinking is that it could be really useful to know which parts of the codebase need the empty behavior.

story645 avatar Mar 09 '25 23:03 story645