John Hunter wrote:
"Eric" == Eric Firing <efiring@...229...> writes:
> John, I think all the ambiguity that you mention below comes
> from one source: the use of a single float to indicate a
> greyscale. Do we really need this? It is not supported by
> colors.looks_like_color(). It could be replaced by a string
> representation of the float (e.g., '0.75') or by a more
> specific string, such as 'g0.75' or 'grey0.75'. I think
> this would be a big net gain for mpl. We lose a lot of
> flexibility, convenience, and consistency by allowing the
> float-is-grey form.
this is a bug in looks_like_color -- ColorConverter, for example,
I suspect that all support of this form does occur via ColorConverter; it is interesting that the looks_like_color bug has not caused objections. looks_like_color is used in only two places: Axes.quiver, which therefore does not support the present float-as-grayscale form, and Collection._get_color. The consequence is that the collection rc settings also do not support float-as-grayscale, but nobody has noticed, or if they have, they have not been greatly bothered.
I also suspect that we should not have looks_like_color at all--it probably makes more sense to simply try to convert the object, and catch an exception if it is not convertable. If the object does look like a color, then chances are one wants to convert it anyway, so why go through most of the logic twice. (For compatibility, looks_like_color could simply do this--try to convert, return True on success and False on failure.)
What flexibility do we lose by supporting grayscale as float? As long
as we have a policy of how we resolve ambiguity, I think we're OK.
Maybe OK, but not good. It is much better to avoid ambiguity entirely than to have to implement and explain an ambiguity resolution policy, when avoiding the ambiguity entails no loss in flexibility.
Present situation: we have to say something like, "(0.3, 0.4, 0.2) is a single RGB, but (0.3, 0.4) is a pair of greyscales". That's ugly and inconsistent, both from the users' standpoint and in terms of what it requires in the code.
Suggestion: we say, "A color can be specified as a string in any of the following formats: standard color abbreviations, html names, hex, or a floating point number between 0 and 1. Or it can be given as a sequence of three numbers specifying R,G,B on a scale from 0 to 1." Perfectly consistent and understandable, and clear in the code: "if is_string_like(c): convert it, else: pass it on as RGB. This consistency then makes it easy to distinguish between, and transparently handle, the case of a single color versus a sequence of colors.
(I posed everything in terms of RGB rather than RGBA, but the idea is the same.)
Eg, ef we have a four-tuple of floats in a case where it could mean
four grays or one RGB, we can choose to resolve it one way or the
other. I think this is a corner case and wouldn't come up to often.
But when it does come up, sometimes the disambiguation will not do what the user expected. It is a fundamentally bad design, and it will bite people as long as it stays in place.
As long as we have a way of disambiguating, eg adopting your 'g0.75'
or 0.75' as a valid string, we retain flexibility and compatibility.
My proposal retains flexibility and increases simplicity and consistency by sacrificing the compatibility. I think this is a case where it is worth it to do so.
I also use the float-as-grayscale not too infrequently....
But maybe with a long deprecation period, you wouldn't terribly mind occasionally changing (0.2, 0.3) to ('0.2', '0.3')? (I know, it is easy for me because I am not the one who has to deal with it.)