Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ENH]: add a thinner minor grid to 3D plots #31467

@chiavez

Description

@chiavez

Problem

  • it appears that 3D plots do not allow for a minor grid with different line properties from the main one.
  • In particular, it would be nice to have the minor grid to be less thick or of another colour than the main one.

workaround code

  • Claude opus 4.6 wrote the following code for me that works around the missing feature
  • This code might be recycled for the actual internal implementation
def add_minor_grid_3d(
    ax,
    minor_x_vals=None,
    minor_y_vals=None,
    minor_z_vals=None,
    face_xy: int = 0,
    face_zy: int = 0,
    face_zx: int = 0,
    color=(0.7, 0.7, 0.7, 0.12),
    linewidth=0.4,
):
    """Draw minor grid lines on a 3D axes, working around matplotlib's
    limitation where ``ax.grid(which='minor')`` is ignored on ``Axes3D``.

    Each plane of the 3D box has two parallel faces (0 or 1).

    Parameters
    ----------
    ax : Axes3D
        The 3D axes to draw on.
    minor_x_vals, minor_y_vals, minor_z_vals : list[float] | None
        Grid positions along each axis.  ``None`` means no minor grid
        for that axis.
    face_xy : int (0 or 1)
        Which xy-face to draw on.
        0 → z = zlim[0] (bottom), 1 → z = zlim[1] (top).
    face_zy : int (0 or 1)
        Which zy-face to draw on.
        0 → x = xlim[0], 1 → x = xlim[1].
    face_zx : int (0 or 1)
        Which zx-face to draw on.
        0 → y = ylim[0], 1 → y = ylim[1].
    color : color-like
        Line color for minor grid.
    linewidth : float
        Line width for minor grid.
    """
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()
    zlim = ax.get_zlim()
    kw = dict(color=color, linewidth=linewidth)

    # x-grid: lines at constant x, L-shape on the zy-face and xy-face
    if minor_x_vals is not None:
        z_anchor = zlim[face_xy]
        z_other = zlim[1 - face_xy]
        for xv in minor_x_vals:
            if xlim[0] <= xv <= xlim[1]:
                ax.plot(
                    [xv, xv, xv],
                    [ylim[face_zy], ylim[1 - face_zy], ylim[1 - face_zy]],
                    [z_anchor, z_anchor, z_other],
                    **kw,
                )

    # y-grid: lines at constant y, L-shape on the zx-face and xy-face
    if minor_y_vals is not None:
        z_anchor = zlim[face_xy]
        z_other = zlim[1 - face_xy]
        for yv in minor_y_vals:
            if ylim[0] <= yv <= ylim[1]:
                ax.plot(
                    [xlim[face_zx], xlim[1 - face_zx], xlim[1 - face_zx]],
                    [yv, yv, yv],
                    [z_anchor, z_anchor, z_other],
                    **kw,
                )

    # z-grid: lines at constant z, L-shape on the zy-face and zx-face
    if minor_z_vals is not None:
        for zv in minor_z_vals:
            if zlim[0] <= zv <= zlim[1]:
                ax.plot(
                    [xlim[face_zy], xlim[face_zy], xlim[1 - face_zy]],
                    [ylim[face_zx], ylim[1 - face_zx], ylim[1 - face_zx]],
                    [zv, zv, zv],
                    **kw,
                )

Result

Image

Notes:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions