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,
)
Problem
workaround code
Result
Notes:
ax.text2Dcommand. This is because the default command gets cropped away when saved [Bug]: The zlabel on 3D axes will be cut when using '%matplotlib inline' in Jupyter #28117