@@ -2104,25 +2104,28 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
21042104
21052105 padding = np .max (linewidths )
21062106 path_codes = []
2107-
2108- # Calculate maximum marker extent for conservative bounds checking.
2109- # We need to account for marker size, not just position.
2110- max_marker_extent = 0
2107+ path_extents = []
21112108 for i , (path , transform ) in enumerate (self ._iter_collection_raw_paths (
21122109 master_transform , paths , all_transforms )):
2113- if len (path .vertices ):
2114- # Get the bounding box of the transformed marker path.
2115- # Use get_extents() which is more efficient than transforming
2116- # all vertices, and add padding for stroke width.
2117- bbox = path .get_extents (transform )
2118- max_marker_extent = max (max_marker_extent ,
2119- bbox .width / 2 , bbox .height / 2 )
21202110 name = self .file .pathCollectionObject (
21212111 gc , path , transform , padding , filled , stroked )
21222112 path_codes .append (name )
2113+ # Compute the extent of each marker path to enable per-marker
2114+ # bounds checking. This allows us to skip markers that are
2115+ # completely outside the visible canvas while preserving markers
2116+ # that are partially visible.
2117+ if len (path .vertices ):
2118+ bbox = path .get_extents (transform )
2119+ # Store half-width and half-height for efficient bounds checking
2120+ path_extents .append ((bbox .width / 2 , bbox .height / 2 ))
2121+ else :
2122+ path_extents .append ((0 , 0 ))
2123+
2124+ # Create a mapping from path_id to extent for efficient lookup
2125+ path_extent_map = dict (zip (path_codes , path_extents ))
21232126
2124- # Add padding for stroke width.
2125- max_marker_extent += padding
2127+ canvas_width = self . file . width * 72
2128+ canvas_height = self . file . height * 72
21262129
21272130 output = self .file .output
21282131 output (* self .gc .push ())
@@ -2132,13 +2135,13 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
21322135 facecolors , edgecolors , linewidths , linestyles ,
21332136 antialiaseds , urls , offset_position , hatchcolors = hatchcolors ):
21342137
2135- # Skip markers outside visible canvas bounds to reduce PDF size.
2136- # Add max_marker_extent margin to account for marker size - a marker
2137- # may be partially visible even if its center is outside the canvas.
2138- canvas_width = self . file . width * 72
2139- canvas_height = self . file . height * 72
2140- if not (- max_marker_extent <= xo <= canvas_width + max_marker_extent
2141- and - max_marker_extent <= yo <= canvas_height + max_marker_extent ):
2138+ # Skip markers completely outside visible canvas bounds to reduce
2139+ # PDF file size. Use per- marker extents to handle large markers
2140+ # correctly: only skip if the marker's bounding box doesn't
2141+ # intersect the canvas at all.
2142+ extent_x , extent_y = path_extent_map [ path_id ]
2143+ if not (- extent_x <= xo <= canvas_width + extent_x
2144+ and - extent_y <= yo <= canvas_height + extent_y ):
21422145 continue
21432146
21442147 self .check_gc (gc0 , rgbFace )
0 commit comments