Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.1k
Fix PDF bloat for off-axis scatter with per-point colors#30746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
4104dd5f95d7611f3b3c31c3e6053ef8b23File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2104,11 +2104,28 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms, | ||
| padding = np.max(linewidths) | ||
| path_codes = [] | ||
| path_extents = [] | ||
| for i, (path, transform) in enumerate(self._iter_collection_raw_paths( | ||
| master_transform, paths, all_transforms)): | ||
| name = self.file.pathCollectionObject( | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Does this write something into the file our only update our Python side sate? ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. It does not write into file immediately but seems it writes after all drawing is done. Let me fix this by creating path templates only for used path_ids and compute extents for creted paths. | ||
| gc, path, transform, padding, filled, stroked) | ||
| path_codes.append(name) | ||
| # Compute the extent of each marker path to enable per-marker | ||
| # bounds checking. This allows us to skip markers that are | ||
| # completely outside the visible canvas while preserving markers | ||
| # that are partially visible. | ||
| if len(path.vertices): | ||
| bbox = path.get_extents(transform) | ||
| # Store half-width and half-height for efficient bounds checking | ||
| path_extents.append((bbox.width / 2, bbox.height / 2)) | ||
| else: | ||
| path_extents.append((0, 0)) | ||
| # Create a mapping from path_id to extent for efficient lookup | ||
| path_extent_map = dict(zip(path_codes, path_extents)) | ||
| canvas_width = self.file.width * 72 | ||
| canvas_height = self.file.height * 72 | ||
| output = self.file.output | ||
| output(*self.gc.push()) | ||
| @@ -2118,6 +2135,28 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms, | ||
| facecolors, edgecolors, linewidths, linestyles, | ||
| antialiaseds, urls, offset_position, hatchcolors=hatchcolors): | ||
| # 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): | ||
| continue | ||
| self.check_gc(gc0, rgbFace) | ||
| dx, dy = xo - lastx, yo - lasty | ||
| output(1, 0, 0, 1, dx, dy, Op.concat_matrix, path_id, | ||
Uh oh!
There was an error while loading.Please reload this page.