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

如何在Matplotlib中为3D曲面图与XY平面等高线图添加对应垂直线

如何在Matplotlib中为3D曲面图与XY平面等高线图添加对应垂直线

我完全懂你想要的效果——让3D曲面和XY平面上的每条等高线之间都连上对应的垂直线,就像你参考的示例图那样。你的现有代码已经搭好了基础框架,只需要调整部分逻辑,让程序自动识别每条等高线的位置,批量生成垂直线就行,不用再手动硬编码啦!

下面是修改后的完整代码,我会在后面给你拆解关键的改动点:

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

# Create a quadratic surface
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = X**2 + Y**2  # Quadratic surface
Z = Z + 20

# Mask a circular region (e.g., radius > 2)
mask = (X**2 + Y**2) > 4
Z_masked = np.ma.masked_where(mask, Z)

# Create plot
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# Plot the surface
surf = ax.plot_surface(X, Y, Z_masked, cmap=cm.viridis, edgecolor='none', alpha=0.8)

# Add contours on the XY plane at Z_min level
z_min = Z_masked.min() - 20
contour = ax.contour(X, Y, Z_masked, zdir='z', offset=z_min, colors='black', linewidths=1)

# 关键改动:为每条等高线添加对应垂直线
for coll in contour.collections:
    # 获取当前等高线的所有路径数据
    paths = coll.get_paths()
    for path in paths:
        # 提取路径上的XY坐标点
        verts = path.vertices
        # 每隔10个点画一条线,避免垂直线过于密集导致图面混乱
        for i, (x_v, y_v) in enumerate(verts):
            if i % 10 == 0:
                # 计算曲面对应该XY点的Z值(因为我们知道Z的表达式,直接计算更高效)
                z_surface = x_v**2 + y_v**2 + 20
                # 绘制垂直线:从XY平面的(x_v, y_v, z_min)到曲面上的(x_v, y_v, z_surface)
                ax.plot([x_v, x_v], [y_v, y_v], [z_min, z_surface],
                        color=coll.get_edgecolor()[0], linewidth=1, alpha=0.7)

# Labels and legend
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')

# Show plot
plt.show()

关键改动说明:

  1. 遍历等高线集合:contour.collections包含了所有绘制出的等高线对象,我们循环遍历每一条等高线。
  2. 提取等高线坐标:通过path.vertices获取每条等高线上的所有XY坐标点,这些点就是我们要画垂直线的起点(在Z_min平面上)。
  3. 计算曲面对应Z值:因为我们的曲面是明确的二次函数,直接用z_surface = x_v**2 + y_v**2 + 20计算对应点的Z值;如果你的数据是复杂的实测数据,可以用插值获取对应XY点的Z值,示例代码如下:
    from scipy.interpolate import griddata
    # 准备插值所需的原始点和对应Z值
    points = np.column_stack((X.ravel(), Y.ravel()))
    values = Z_masked.ravel()
    # 对当前XY点插值得到Z值
    z_surface = griddata(points, values, (x_v, y_v), method='linear')
    
  4. 控制垂直线密度:用i % 10 == 0只每隔10个点画一条线,避免大量垂直线堆叠导致图面杂乱,你可以根据自己的需求调整这个间隔值。
  5. 颜色对应:垂直线的颜色和对应等高线的颜色保持一致,这样能更清晰地看出每条垂直线属于哪条等高线。

这样修改后,你就能得到和参考图类似的效果——每条等高线都有对应的垂直线连接到3D曲面上,对应关系一目了然~

备注:内容来源于stack exchange,提问作者skm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:08:02