Snap markers to subpixels instead of whole ones - #32108
Conversation
We cache the marker for performance, but this causes it to look very pixel-grid aligned, especially if there are multiple in a regular pattern, or they are animated. Apply the same algorithm as mplcairo noted by @anntzer in matplotlib#7233, specifically, render and cache the marker in *n_subdiv* levels in each direction, and pick the closest one for each marker. Fixes matplotlib#7233
| // TODO: Pixel markers *must* be drawn snapped. | ||
| auto const& is_pixel_marker = false; | ||
| // py_eq(marker_path, PIXEL_MARKER.attr("get_path")()) | ||
| // && marker_trans == PIXEL_MARKER.attr("get_transform")().cast<agg::trans_affine>(); |
There was a problem hiding this comment.
mplcairo special-cases the pixel marker; I have not checked how that turns out or whether that is necessary.
There was a problem hiding this comment.
IIRC the idea is that not snapping the pixel marker results in it being smeared across two pixels, whereas it would otherwise look sharp (exactly one pixel filled) on a raster output.
| auto marker_path_snapped = PathSnapper{ | ||
| marker_path_nan_removed, | ||
| gc.snap_mode, marker_path.total_vertices(), | ||
| points_to_pixels(gc.linewidth)}; |
There was a problem hiding this comment.
I'm not 100% certain we should be snapping here for each of the cached subpixel markers. It affects a lot more test images if we drop this though.
There was a problem hiding this comment.
From a quick look mplcairo disables snapping when generating subpixel markers, which still makes sense to me? (Actually, if you snap, I don't see how you can benefit from subpixel positioning.)
Maybe the issue with test images is with ticks, which are effectively markers and should indeed be drawn snapped? Can that be fixed by explicitly forcing snapping on them? (I didn't re-check snap control semantics, but maybe(?) it makes sense that if snapping is requested on the edges of a Line2D, then it is also enabled on the markers at its vertices?)



PR summary
We cache the marker for performance, but this causes it to look very pixel-grid aligned, especially if there are multiple in a regular pattern, or they are animated.
Apply the same algorithm as mplcairo noted by @anntzer in #7233, specifically, render and cache the marker in n_subdiv levels in each direction, and pick the closest one for each marker.
Fixes #7233
AI Disclosure
None
PR checklist