You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib 3D绘图:如何让茎图显示在2D等高填充图前方?

解决方案

问题根源

Matplotlib的3D坐标轴渲染优先级由元素的z坐标决定,而非zorder参数。原代码中contourf和茎图的底部都在z=0层级,导致茎被遮挡。此外,默认茎图样式较细,需调整以接近柱状图效果。

修复后的茎图版本代码

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 101)
y = np.linspace(-1, 1, 101)

X, Y = np.meshgrid(x, y)
z = np.exp(-(X**2) - Y**2)

x0 = [-0.5, 0, 0.5]
y0 = [-0.5, 0, 0.5]
z0 = [0.5, 1, 2]

fig, ax = plt.subplots(subplot_kw=dict(projection="3d"))
# 将等高填充图置于z=-0.01层级,低于茎的起始位置z=0
ax.contourf(
    x,
    y,
    z,
    zdir="z",
    offset=-0.01,
    cmap='viridis'
)
# 绘制茎图,隐藏基线并加粗茎条
ps = ax.stem(x0, y0, z0, basefmt=" ", linefmt="k-", markerfmt="ko")
ps[0].set_linewidth(8)  # 调整茎宽,贴近柱状图视觉效果

# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

柱状图替代方案

若需要完全的柱状图效果,可使用bar3d替代stem:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 101)
y = np.linspace(-1, 1, 101)

X, Y = np.meshgrid(x, y)
z = np.exp(-(X**2) - Y**2)

x0 = [-0.5, 0, 0.5]
y0 = [-0.5, 0, 0.5]
z0 = [0.5, 1, 2]
dx = dy = 0.1  # 柱子的x、y方向宽度

fig, ax = plt.subplots(subplot_kw=dict(projection="3d"))
ax.contourf(
    x,
    y,
    z,
    zdir="z",
    offset=-0.01,
    cmap='viridis'
)
# 从z=0起始绘制3D柱状图
for xi, yi, zi in zip(x0, y0, z0):
    ax.bar3d(xi - dx/2, yi - dy/2, 0, dx, dy, zi, color='k', alpha=0.7)

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

关键调整说明

  • 将contourf的offset设为-0.01,让等高图处于茎/柱子下方,避免遮挡。
  • 茎图中用basefmt=" "隐藏默认基线,调整linewidth加粗茎条。
  • 柱状图通过bar3d直接绘制带宽度的柱子,完全贴合需求。

内容的提问来源于stack exchange,提问作者mmonti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:05:07