Skip to content

ENH: add geometric axlim clipping for 3D surfaces and line collections#31732

Open
DanielBetschinske wants to merge 1 commit into
matplotlib:mainfrom
DanielBetschinske:mplot3d-geometric-surface-clipping
Open

ENH: add geometric axlim clipping for 3D surfaces and line collections#31732
DanielBetschinske wants to merge 1 commit into
matplotlib:mainfrom
DanielBetschinske:mplot3d-geometric-surface-clipping

Conversation

@DanielBetschinske
Copy link
Copy Markdown

PR summary

Related to #25804.

This PR adds an opt-in geometric axes-limit clipping mode for selected
mplot3d polygon and line artists.

Currently, axlim_clip=True hides/masks surface patches or line segments when
vertices fall outside the current 3D axes view limits. For surfaces and
wireframes this can leave visible gaps at the axes-limit boundary.

This PR keeps the existing behavior as the default:

ax.plot_surface(..., axlim_clip=True)
ax.plot_wireframe(..., axlim_clip=True)

and adds a new explicit mode:

ax.plot_surface(..., axlim_clip=True, axlim_clip_mode="clip")
ax.plot_wireframe(..., axlim_clip=True, axlim_clip_mode="clip")

With axlim_clip_mode="clip", surface polygons and wireframe line segments are
geometrically clipped to the six planes of the current 3D axes view-limit box.

The implementation adds private clipping helpers in
mpl_toolkits.mplot3d.art3d for:

  • clipping 3D polygons against an axis-aligned box,
  • clipping 3D line segments against an axis-aligned box.

The new keyword is forwarded from Axes3D.plot_surface and
Axes3D.plot_wireframe to the underlying Poly3DCollection and
Line3DCollection.

This PR intentionally keeps the scope limited to surfaces and line collections.
Point-like artists such as scatter and text continue to use the existing
hide/mask behavior, because they do not have 3D geometry that can be
meaningfully cut.

Minimum example:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

fig, axs = plt.subplots(
    1, 3,
    subplot_kw={"projection": "3d"},
    figsize=(10, 4),
    layout="constrained",
)

x = np.arange(-5, 5, 0.25)
y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.hypot(X, Y))

cases = [
    ("unclipped", dict(axlim_clip=False)),
    ('axlim_clip_mode="hide"', dict(axlim_clip=True, axlim_clip_mode="hide")),
    ('axlim_clip_mode="clip"', dict(axlim_clip=True, axlim_clip_mode="clip")),
]

for ax, (title, clip_kwargs) in zip(axs, cases):
    ax.plot_surface(
        X, Y, Z,
        cmap=cm.coolwarm,
        linewidth=0,
        antialiased=False,
        **clip_kwargs,
    )
    ax.set_title(title)
    ax.set_xlim(-3.2, 3.2)
    ax.set_ylim(-3.0, 2.6)
    ax.set_zlim(-0.45, 0.85)

plt.show()

AI Disclosure

I used ChatGPT to help prototype the clipping approach, identify edge cases,
draft tests and gallery-example text, and iterate on implementation details.
I reviewed and tested the resulting changes locally before submitting this PR.

PR checklist

  • [N/A] "closes #0000" is in the body of the PR description to link the related issue
  • new and changed code is tested
  • Plotting related features are demonstrated in an example
  • New Features and API Changes are noted with a directive and release note
  • Documentation complies with general and docstring guidelines

@github-actions
Copy link
Copy Markdown

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks. We also ask that you please finish addressing any review comments on this PR and wait for it to be merged (or closed) before opening a new one, as it can be a valuable learning experience to go through the review process.

You can also join us on discourse chat for real-time discussion.

For details on testing, writing docs, and our review process, please see the developer guide.
Please let us know if (and how) you use AI, it will help us give you better feedback on your PR.

We strive to be a welcoming and open project. Please follow our Code of Conduct.

@scottshambaugh
Copy link
Copy Markdown
Contributor

scottshambaugh commented May 22, 2026

Given the lack of any image tests or graphical examples, and heavy reliance on AI, I am not convinced that this is behaving correctly or properly covers edge cases. Please explain why you chose this approach and what alternatives were considered.

See #30553 for a draft implementation and #29373 for more discussion on how to tackle this issue.

@scottshambaugh scottshambaugh added the status: autoclose candidate PRs that are not yet ready for review and may be automatically closed in two weeks label May 22, 2026
@github-actions
Copy link
Copy Markdown

⏰ This pull request might be automatically closed in two weeks from now.

Thank you for your contribution to Matplotlib and for the effort you have put into this PR. This pull request does not yet meet the quality and clarity standards needed for an effective review. Project maintainers have limited time for code reviews, and our goal is to prioritize well-prepared contributions to keep Matplotlib maintainable.

Matplotlib maintainers cannot provide one-to-one guidance on this PR. However, if you ask focused, well-researched questions, a community member may be willing to help. 💬

To increase the chance of a productive review:

As the author, you are responsible for driving this PR, which entails doing necessary background research as well as presenting its context and your thought process. If you are a new contributor, or do not know how to fulfill these requirements, we recommend that you familiarize yourself with Matplotlib's development conventions or engage with the community via our Discourse or one of our meetings before submitting code.

If you substantially improve this PR within two weeks, leave a comment and a team member may remove the status: autoclose candidate label and the PR stays open. Cosmetic changes or incomplete fixes will not be sufficient. Maintainers will assess improvements on their own schedule. Please do not ping (@) maintainers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation: examples files in galleries/examples first-contribution status: autoclose candidate PRs that are not yet ready for review and may be automatically closed in two weeks topic: mplot3d

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants