FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Line2D can snap incorrectly and request snap(x)(y) parameters · Issue #19054 · matplotlib/matplotlib · GitHub

Repository navigation

Line2D can snap incorrectly and request snap(x)(y) parameters #19054

Closed

Description

Bug report

Bug summary

Axes.plot produces thin lines (1, 3, ... px) which may snap incorrectly relative to Rectangles depending on the dpi and Axes position, in other words, the width of the left and bottom margins. In such cases, non-snapped lines achieve the desired outcome.

Code for reproduction

from matplotlib.pyplot import figure
from matplotlib.patches import Rectangle

fig = figure(figsize=(10,10), dpi=155)
ax = fig.add_axes([0.09, 0.1, 0.8, 0.86])
ax.axis([0, 1240, 0, 1333])
ax.minorticks_on()
ax.grid(which='both', ls=':')

ax.add_patch(Rectangle((700,800), 200, 3, snap=True))
ax.add_patch(Rectangle((800,700), 3, 200, snap=True))
lw = 1 * 72 / 155
ax.plot([890,801.5,801.5], [801.5,801.5,890], c='lime', lw=lw, snap=True)
ax.plot([710,801.5,801.5], [801.5,801.5,710], c='red', lw=lw, snap=False)

fig.savefig("snap.png")

The Axes relative position of (0.09, 0.1) is chosen on purpose so that the left margin is 0.09 * 10 in * 155 dpi = 139.5 px and the bottom one is 155 px. Also note that the Axis are scaled to be 1 pixel : 1 unit.

Actual outcome

Zoom in to view individual pixels...

Expected outcome

That the lime line snaps correctly in the middle of the blue Rectangles. Note how the horizontal non-snapped red line works as desired.

Feature request

To implement something equivalent to snapx and snapy following scalex and scaley trend. #15595 might change this trend though. This feature could be used to work around this issue, but I think the solutions should be independent. Will split this request into another issue if it's welcomed.

Matplotlib version

  • Operating system: Windows 10
  • Matplotlib version: 3.3.3
  • Matplotlib backend: module://ipykernel.pylab.backend_inline
  • Python version: 3.9.0

Python installed via official installer. Matplotlib installed via pip.

Activity

  1. changed the title [-]Line2D snaps incorrectly relative to Rectangle and request snap(x)(y) parameters[/-] [+]Line2D can snap incorrectly and request snap(x)(y) parameters[/+] on Dec 4, 2020
  2. timhoffm commented on Dec 28, 2020

    Member

    This is a numeric issue. If you replace the 801.5 y-values by 801.50000000001 everything looks right, i.e.

    ax.plot([890,801.5,801.5], [801.50000000001,801.50000000001,890], c='lime', lw=lw, snap=True)
    

    I'm not clear if we can do anything about this.

  3. anntzer commented on Dec 29, 2020

    Contributor

    It's not clear we can do anything about it? The point of snapping is that there is a critical value below which everything gets snapped to one pixel row, and above which everything gets snapped to the next pixel row...

  4. tacaswell commented on Dec 29, 2020

    Member

    xref #8265 for discussion and some code on floor vs round.

  5. Ernesto1971 commented on Dec 30, 2020

  6. jklymak commented on Dec 30, 2020

    Member

    I'm going to close, in the same spirit as #18945. Numbers right on the border of 0.5 are going to flop between either side arbitrarily, based on round off error.

    @Ernesto1971 we can't change your subscription status on GitHub. You have to do that yourself.

  7. alexiscoutinho commented on Mar 9, 2021

    ContributorAuthor

    @timhoffm I think this is more than a numeric issue. @anntzer I found the thresholds and there are still some unanswered questions... The below thresholds are between the bottom/left pixel row/column and middle pixel row/column of the original blue cross for the x and y axis:

    x (offsetting the vertical artists):
    rectangle: left column < 801.0 <= middle column
    snapped line: left column < 801.0 <= middle column
    normal line: left column < ~801.5 < middle column (threshold determines where most of the opacity will be)

    y (offsetting the horizontal artists):
    rectangle: bottom row <= 800.5 < middle row
    snapped line: bottom row <= 801.5 < middle row
    normal line: bottom row < ~801.0 < middle row

    @jklymak Even if we ignore the exact transition points (<= or <), bizarre snapping still occurs:

    • Why are the thresholds between snapped and not snapped artists for both axis offset by half? Based on Artist.set_snap, 1px lines between 2 pixels should be interpolated between them for not snapped lines. Since the same x or y value/region that maps to a pixel border (causing interpolation) could be used for both line types, why does the snapped line not interpret this same value as a threshold/border?
    • The x thresholds are offset from the y thresholds by +0.5, except the snapped line threshold, which is offset by -0.5, why? Furthermore, this causes the absurd case where a line at y=801.5 would be drawn outside a rectangle between y=801 and y=803.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL