You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Path snapping does not respect quantization scale appropriate for Retina displays #2697
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.
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...)
Activity
mdboom commentedon Dec 30, 2013
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...)
efiring commentedon Feb 15, 2016
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.
mdboom commentedon Mar 21, 2016
Fixed by #6178