Skip to content

wrong x-position of marker with drawstyle='steps-xxx' #11031

Closed

Description

@pierre-haessig

Bug report

Hello, as discussed on matplotlib-devel, there is a unexpected change in Matplotlib 2.2 when plotting lines and markers (e.g. style 'D-') combined with drawstyle='steps-post' (steps-pre' and 'steps-mid' as well).

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 6, 7)
y = np.sin(x)
plt.plot(x, y, 'D-', drawstyle='steps-post')

Actual outcome

In Matplotlib 2.2.2, markers are drawn at each "line break".

image

Running the same script with drawstyle='steps-mid' yields markers at half-integer positions (except for those at the end)

Expected outcome

In all previous Matplotlib versions, the marker was placed at the exact x-position of the input data (which is the left of each segment for drawstyle='steps-post'). I didn't do the bissection to know when the changed happen, but I suspect it's quite new (2.1 → 2.2 ?).

Matplotlib version

  • Matplotlib version: 2.2.2
  • Python version: 3.6

Activity

  1. dstansby commented on Apr 12, 2018

    @dstansby
    Member

    Bisects to 722f405, so quite a long time ago actually! ping @anntzer

  2. anntzer commented on Apr 12, 2018

    @anntzer
    Contributor

    Something like

    diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py
    index cc8c61754..738a2396f 100644
    --- a/lib/matplotlib/lines.py
    +++ b/lib/matplotlib/lines.py
    @@ -745,6 +745,8 @@ class Line2D(Artist):
                 subslice = slice(max(i0 - 1, 0), i1 + 1)
                 self.ind_offset = subslice.start
                 self._transform_path(subslice)
    +        else:
    +            subslice = None
     
             transf_path = self._get_transformed_path()
     
    @@ -804,7 +806,15 @@ class Line2D(Artist):
                 gc.set_antialiased(self._antialiased)
     
                 marker = self._marker
    -            tpath, affine = transf_path.get_transformed_points_and_affine()
    +
    +            # Markers *must* be drawn ignoring the drawstyle.
    +            with cbook._setattr_cm(
    +                    self, _drawstyle="default", _transformed_path=None):
    +                self.recache()
    +                if subslice:
    +                    self._transform_path(subslice)
    +                tpath, affine = (self._get_transformed_path()
    +                                 .get_transformed_points_and_affine())
                 if len(tpath.vertices):
                     # subsample the markers if markevery is not None
                     markevery = self.get_markevery()
    

    fixes the issue, but that's pretty horrible from a performance point of view. Don't have the time to turn this into a proper PR right now.

  3. added this to the v2.2.3 milestone on Jun 10, 2018
  4. pierre-haessig commented on Jun 11, 2018

    @pierre-haessig
    SponsorContributorAuthor

    great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions