Matplotlib -- mplot3d: 如何在3D图中将triplot投影到z=0轴上?

2 投票
1 回答
1370 浏览
提问于 2025-04-18 10:34

我想在已知的三角形区域上绘制一个有两个变量的函数,基本上是这样的:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import random

def f( x, y):
  if x + y < 1: return 0
  else: return 1

x = [0, 1, 1, 0]
y = [0, 0, 1, 1]
tris = [[0, 1, 3], [1, 2,3]]

fig = plt.figure()
ax = fig.add_subplot( 121)
ax.triplot( x, y, tris)

xs = [random.random() for _ in range( 100)]
ys = [random.random() for _ in range( 100)]
zs = [f(xs[i], ys[i]) for i in range( 100)]
ax2 = fig.add_subplot( 122, projection='3d')
ax2.scatter( xs, ys, zs)
plt.show()

理想情况下,我想把这两个子图合并成一个,通过把三角形投影到z=0的轴上。我知道在其他类型的二维图中可以做到这一点,但在triplot中不行。我想知道我能否实现我想要的效果?

附注:这是我现在使用的实际实现的一个大大简化版本,所以随机散布的样子可能看起来有点奇怪。

1 个回答

1

我不是专家,但这个问题挺有意思的。在研究了一下之后,我觉得我找到了一个接近的解决办法。我手动创建了一个三角剖分对象,然后把它和一个全是零的z列表传给了plot_trisurf,这样就把三角形放到了z=0的正确位置。

import matplotlib.pyplot as plt
import matplotlib.tri as tri
from mpl_toolkits.mplot3d import Axes3D
import random

def f( x, y):
    if x + y < 1: return 0
    else: return 1

x = [0, 1, 1, 0]
y = [0, 0, 1, 1]
tris = [[0, 1, 3], [1, 2,3]]
z = [0] * 4

triv = tri.Triangulation(x, y, tris)

fig = plt.figure()
ax = fig.add_subplot( 111, projection='3d')
trip = ax.plot_trisurf( triv, z )
trip.set_facecolor('white')

xs = [random.random() for _ in range( 100)]
ys = [random.random() for _ in range( 100)]
zs = [f(xs[i], ys[i]) for i in range( 100)]

ax.scatter( xs, ys, zs)
plt.show()

补充说明:我在Poly3DCollection上添加了set_facecolor的调用,这样它的颜色就变成白色,而不是跟随颜色映射。可以根据需要进行调整...

撰写回答