Giter Club home page Giter Club logo

Comments (2)

ksunden avatar ksunden commented on June 14, 2024

linestyle is a bit of a strange argument to be passing to scatter. It is not entirely wrong, just may not do what you expect.

If you are expecting a line between your points, then plot is the method to use.

What it is actually controlling, though, is the lines of the markers themselves. This is actually done through **kwargs eventually being passed through the Collection.

Now, given that that is what you want, "" is itself a bit of an edge case, as that is indicated not to draw the line, rather than really adjusting how it is drawn.

In Line2D, the various forms of "linestyle for not having the line" are normalized to "None":

if ls in [' ', '', 'none']:
ls = 'None'

(And then handled within Line2D specific code to not draw anything...)

And In fact if you pass plt.scatter(..., linestyle="None") it does not error, but a line is still drawn...

A quick way to get the desired effect would be to use linewidth=0 instead of adjusting line style. This is actually what is done internally for Patch objects when linestyle is set to "None" (or "", or " ", etc).

Anyway, the Collection set_linestyle mostly wraps mpl.lines._get_dashpattern, just handling the broadcasting since collections are plural:

def set_linestyle(self, ls):
"""
Set the linestyle(s) for the collection.
=========================== =================
linestyle description
=========================== =================
``'-'`` or ``'solid'`` solid line
``'--'`` or ``'dashed'`` dashed line
``'-.'`` or ``'dashdot'`` dash-dotted line
``':'`` or ``'dotted'`` dotted line
=========================== =================
Alternatively a dash tuple of the following form can be provided::
(offset, onoffseq),
where ``onoffseq`` is an even length tuple of on and off ink in points.
Parameters
----------
ls : str or tuple or list thereof
Valid values for individual linestyles include {'-', '--', '-.',
':', '', (offset, on-off-seq)}. See `.Line2D.set_linestyle` for a
complete description.
"""
try:
dashes = [mlines._get_dash_pattern(ls)]
except ValueError:
try:
dashes = [mlines._get_dash_pattern(x) for x in ls]
except ValueError as err:
emsg = f'Do not know how to convert {ls!r} to dashes'
raise ValueError(emsg) from err
# get the list of raw 'unscaled' dash patterns
self._us_linestyles = dashes
# broadcast and scale the lw and dash patterns
self._linewidths, self._linestyles = self._bcast_lwls(
self._us_lw, self._us_linestyles)

The _get_dashpattern function actually returns the same thing for "None" or "solid":

if style in ['solid', 'None']:

But it does not handle all of the aliases ("", " ", etc). And arguably can't... since "not drawing" is different than "what is the offset and dashpattern for the thing I should draw?"

Now, one other wrinkle here is that when given "", the set_linestyle code for Collection will actually result in an empty list (the try section errors, which brings it to the except which loops over the empty string, resulting an an empty list... other aliases will result in an error message at call time):

try:
dashes = [mlines._get_dash_pattern(ls)]
except ValueError:
try:
dashes = [mlines._get_dash_pattern(x) for x in ls]
except ValueError as err:
emsg = f'Do not know how to convert {ls!r} to dashes'
raise ValueError(emsg) from err

The last wrinkle is how it is treated by backends, as agg-based renderers seem to be okay with that? (I think it may actually be failing to draw the collection at all, possibly due to a zip including the empty list? but does not error.) The pdf backend errors

Docs wise, the "None" case, which appears in the Line2D.set_linestyle docstring table is actually left out of the Collection.set_linestyle docstring, though "" does still appear in the parameters section listed, and it crosslinks to the Line2D version as the more complete reference.

Proposed solution:

  • Handle aliasing/special casing of "None" in Collections.set_linestyle
  • Handle interpretting the special case in Collections._bcast_lwls to set lw to 0 for ls="None".

TL;DR:

  • Right now you can use linewidth=0 to get the desired effect
  • In all, internally it is a bit frustrating that everything implements turning off a line via line styling ever so slightly differently, but I think we should likely support it here

from matplotlib.

vegardjervell avatar vegardjervell commented on June 14, 2024

Thank you for the thorough and quick response! I'm aware that it really doesn't make sense to pass a linestyle to scatter, but I often use plot(*args, linestyle='') if I'm scattering many points with the same color, as scatter can be quite a bit slower if there are many points (at least I remember that being the case some years ago, please correct me if I'm wrong). The reason I came across this was that I modified some code to set different colors on the points, and forgot to remove the linestyle kwarg (which I think may be not-so-uncommon to do).

The reason I think it qualifies as a bug is maybe more the cryptic error message that is thrown, specifically when saving as a pdf, when saving as png and show work as expected.

I think it would be a perfectly reasonable fix to just throw an error if linestyle is passed to scatter, but given that this can be handled elegantly in Collections.set_linestyle or Collections._bcast_lwls that would of course be preferable.

from matplotlib.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.