From 4240868e0a78894251211488a68304e387c9b69b Mon Sep 17 00:00:00 2001 From: Ayush Pandey Date: Mon, 6 Jul 2026 01:14:38 +0530 Subject: [PATCH] Fix PDF marker culling with translated master transform --- lib/matplotlib/backends/backend_pdf.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 13890eba0c24..257f398949ff 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -2035,36 +2035,32 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms, gc, path_codes, offsets, offset_trans, facecolors, edgecolors, linewidths, linestyles, antialiaseds, urls, offset_position, hatchcolors=hatchcolors): + m = master_transform.get_matrix() + tx = m[0, 2] + ty = m[1, 2] + xo2 = xo + tx + yo2 = yo + ty # Optimization: Fast path for markers with centers inside canvas. # This avoids the dictionary lookup for the common case where # markers are visible, improving performance for large scatter plots. if 0 <= xo <= canvas_width and 0 <= yo <= canvas_height: - # Marker center is inside canvas - definitely render it self.check_gc(gc0, rgbFace) dx, dy = xo - lastx, yo - lasty output(1, 0, 0, 1, dx, dy, Op.concat_matrix, path_id, Op.use_xobject) lastx, lasty = xo, yo continue - - # Marker center is outside canvas - check if partially visible. - # Skip markers completely outside visible canvas bounds to reduce - # PDF file size. Use per-marker extents to handle large markers - # correctly: only skip if the marker's bounding box doesn't - # intersect the canvas at all. extent_x, extent_y = path_extent_map[path_id] - if not (-extent_x <= xo <= canvas_width + extent_x - and -extent_y <= yo <= canvas_height + extent_y): + if not (-extent_x <= xo2 <= canvas_width + extent_x + and -extent_y <= yo2 <= canvas_height + extent_y): continue - self.check_gc(gc0, rgbFace) dx, dy = xo - lastx, yo - lasty output(1, 0, 0, 1, dx, dy, Op.concat_matrix, path_id, - Op.use_xobject) + Op.use_xobject) lastx, lasty = xo, yo output(*self.gc.pop()) - def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): # docstring inherited