Skip to content

Path snapping does not respect quantization scale appropriate for Retina displays #2697

Closed

Description

@piannucci

Here's a toy version of something I'm working on:

import numpy as np, pylab as pl
N = M = 10
n = 1000
a = (np.random.standard_normal((n,N,M)) + 1j * np.random.standard_normal((n,N,M))) * .5**.5
b = np.linalg.svd(a)
pl.clf()
for i in xrange(b[1].shape[1]):
    _=pl.hist(b[1][:,i], bins=100, histtype='step', normed=True)

If you run this with the macosx backend on a Retina display and carefully resize the window, you will find that the path snapping algorithm is snapping to the nearest two-pixel boundary, rather than the intended behavior of snapping to the nearest one-pixel boundary.

I speculate that this is also an issue with marker placement and hatching.

Two solutions are apparent.

One is for the macosx backend to do a little dance of rescaling the transform matrices before and after passing paths through the path iterator. This seems like a pain and not very portable. I believe that the other backends will be growing high-DPI flavors soon! [edit: just took a look and it seems like only the macosx backend uses the PathCleanupIterator. Is that correct?]

The other solution is for the path iterator to take the image magnification factor as an argument, and thread this through the code to the actual path snapper.

Incidentally, we might consider renaming the image magnification factor since it matters for vectors too.

Activity

  1. mdboom commented on Dec 30, 2013

    @mdboom
    Member

    Yes, at present, the path snapper is hard coded to snap to integral values (+ 0.5 in the case of odd-valued line widths). I think, as you suggest, we should extend this to snap to an arbitrary fraction of a pixel, and the mac os-x backend would pass the current scale factor to it. Bonus points for keeping the fast path in the common case for integral snapping.

    The Agg backend uses the same PathSnapper code as the OS-X backend, but only the OS-X backend uses PathCleanupIterator, which is really just a bridge between the Objective-C that the osx backend uses and the C++ that the rest of matplotlib uses.

    I don't know if the other backends will be affected by this. The Agg backend already handles abritrary DPI correctly. OS-X Quartz is the only API I'm aware of that handles high API in such a strange way (I know Apple did that for backward compatibility, but it does make things more complex...)

  2. modified the milestones: v1.4.x, on Aug 17, 2014
  3. modified the milestones: , on Feb 15, 2016
  4. efiring commented on Feb 15, 2016

    @efiring
    Member

    The fix for this will probably be either via a partly new backend with agg for OSX, and/or the use of qt5agg, which should support Retina displays.

  5. mdboom commented on Mar 21, 2016

    @mdboom
    Member

    Fixed by #6178

  6. modified the milestones: , on Mar 28, 2016
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

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions