Open gmamon opened 3 years ago
agree this would be nice, some related discussion is at xref: #17850
With plot
, you can do ax.plot(x, y, marker='o', fillstyle='none')
, though annoyingly it seems you can't do that with scatter
. However, maybe you don't need scatter
?
This is achievable in scatter by plt.scatter(x, y, marker=MarkerStyle('o', fillstyle='none'))
.
marker
(and fillstyle
) are internally passed to MarkerStyle
.
What is asked here is an extension of the MarkerStyle
parser so that MarkerStyle('oo') == Marker('o', fillstyle='none')
. This is only about convenience not about new functionality.
First, the fundamental question to answer is if the increased usability outweights the redundancy.
Some additional specific aspects:
marker='oo'
readable enough or is that too cryptic.fmt
mini language in plot
currently assumes that markers are single characters. This would have to be extended - I assume that we would want the same marker specification in plot
and in scatter
.Is
marker='oo'
readable enough or is that too cryptic.
This might conflict conceptually with hatching, where doubling the character increases the density, whereas this decreases the ink for the marker.
Here it‘s not doubling, but an added o for open (an open square is 'so'). Technically there is no conceptual overlap. The question is rather if 'oo' is readable enough. A more verbose option could be 'o(open)' or 'open-o' or similar.
annoyingly it seems you can't do that with scatter
Indeed, something like scatter([1, 2], [3, 4], c=[0, 1], fc="none")
fails to colormap the edgecolors because edgecolor defaults to "face" and then fc="none" wins against the colormapping provided by c
. I actually think that looks like a bug? (it should be possible to colormap ec
while having a fixed fc
)
Would we also have characters for the half fill styles? If so which?
f[ull], l[eft], r[ight], t[op], b[ottom], n[one]
If it's not overkill to expand to three letters, (or I guess two since none=open?)
First, the fundamental question to answer is if the increased usability outweights the redundancy.
To be clear, I think the preferred API should not be manipulating MarkerStyles, but really to make fc="none"
work (as noted in my message above). I don't think scatter(x, y, marker="o", fc="none")
(in fact, that's just scatter(x, y, fc="none")
in the common case of circle markers) is really worse than scatter(x, y, marker="oo")
, and is likely more legible (and if you start writing "o-open" then the difference in length is even less). (In other words, as things are I am :-1: on "oo" or "o-open". In further other words, I don't think minimization of keystroke count should rank highly in API design. (I'm not saying it doesn't matter at all, either.))
As for making fc="none"
work, perhaps the solution would be along the lines of making the default value of ec
not be "face" ("match the facecolor"), but rather the new magic value "mapped" (or "data" or whatever), and likewise for fc
, meaning "the colormapped color"? (and if no data-to-be-colormapped is set, fallback to some rc such as lines.markerfacecolor
or lines.color
? (or we would even introduce another rc for that but that seems overkill))
With
plot
, you can doax.plot(x, y, marker='o', fillstyle='none')
, though annoyingly it seems you can't do that withscatter
. However, maybe you don't needscatter
?
This makes me think that plot
, scatter
and errorbar
should be merged into a single Matplotlib.pyplot function.
I'm +1 on the fc='none' proposal cause that's what I've tried first in the past and was frustrated it didn't work.
@gmamon plot, scatter, and errorbar have different semantics, but I agree we should try to standardize the keyword arguments for manipulating markers.
Actually, looking at the docs of Collection
again, I note that it states
If the Collection's
.ScalarMappable
matrix_A
has been set (via a call to.Collection.set_array
), then at draw time this internal scalar mappable will be used to set thefacecolors
andedgecolors
, ignoring those that were manually passed in.
which is currently not true (even ignoring the edge case of ec="face"
): with pc = scatter([1, 2], [3, 4], ec="r", fc="r"); pc.set_array([0, 1])
the edgecolor is not ignored; colormapping is only applied to the facecolor.
instead of opening a new issue, gonna revive this one. The no fillstyle in scatter is bothering me cause of its inconsistency w/ plot (https://github.com/matplotlib/matplotlib/issues/20360#issuecomment-854166001) so what do folks feel about either:
I'm -1 on the original two-char proposals (marker="oo"). - This is too crypitc.
I'm -0.3 on an expanded string notation or a tuple (symbol, fillstyle) - This is a new type of API and we already have ways to set fillstyle.
I'm +0.5 on scatter growing a fillstyle argument. - This is consistent with plot()
.
Problem
It would be nice to have direct shortcuts for plotting open symbols (e.g. with plt.scatter).
For example,
for open circles:
plt.scatter(x,y,marker='oo')
open squares:
plt.scatter(x,y,marker='so')
etc.