Matplotlib - 同时绘制 3D 平面和点

Posted

技术标签:

【中文标题】Matplotlib - 同时绘制 3D 平面和点【英文标题】:Matplotlib - Plot a plane and points in 3D simultaneously 【发布时间】:2016-07-03 19:46:06 【问题描述】:

我正在尝试使用 Matplotlib 同时绘制一个平面和一些 3D 点。 我没有错误只是点不会出现。 我可以在不同时间绘制一些点和平面,但不能同时绘制。 部分代码如下所示:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

point  = np.array([1, 2, 3])
normal = np.array([1, 1, 2])

point2 = np.array([10, 50, 50])

# a plane is a*x+b*y+c*z+d=0
# [a,b,c] is the normal. Thus, we have to calculate
# d and we're set
d = -point.dot(normal)

# create x,y
xx, yy = np.meshgrid(range(10), range(10))

# calculate corresponding z
z = (-normal[0] * xx - normal[1] * yy - d) * 1. /normal[2]

# plot the surface
plt3d = plt.figure().gca(projection='3d')
plt3d.plot_surface(xx, yy, z, alpha=0.2)


#and i would like to plot this point : 
ax.scatter(point2[0] , point2[1] , point2[2],  color='green')

plt.show()

【问题讨论】:

@AndreyRubshtein 这有什么关系?您链接到的问题是关于matlab,这是关于matplotlib 嘿@tom,它有一个关于数学公式的解释,在原始问题中称为“计算对应的z” 好的,虽然这不是这个问题和答案的真正目的 顺便提一下:对于 z 分量为零的法线向量,此方法将失败!因此,例如,normal = np.array([1,0,0]) 将抛出 RuntimeWarning: divide by zero encountered in true_divide 并且没有绘制平面! 【参考方案1】:

稍微详细说明数学部分(以及它是如何工作的)可能对某人有用,单位法向量n包含一个点a如下所示:

所以这里的平面方程是 x + y + 2*z = 9,下面的代码可以简单地用于绘制给定的平面:

# create the figure
fig = plt.figure()

# add axes
ax = fig.add_subplot(111,projection='3d')

xx, yy = np.meshgrid(range(10), range(10))
z = (9 - xx - yy) / 2 

# plot the plane
ax.plot_surface(xx, yy, z, alpha=0.5)

plt.show()

使用scatter() 可以简单地绘制要点

【讨论】:

【参考方案2】:

您需要告诉坐标轴您希望将新图添加到坐标轴上的当前图而不是覆盖它们。为此,您需要使用axes.hold(True)

# plot the surface
plt3d = plt.figure().gca(projection='3d')
plt3d.plot_surface(xx, yy, z, alpha=0.2)

# Ensure that the next plot doesn't overwrite the first plot
ax = plt.gca()
ax.hold(True)

ax.scatter(points2[0], point2[1], point2[2], color='green')

更新

正如@tcaswell 在 cmets 中指出的那样,他们正在考虑停止对hold 的支持。因此,更好的方法可能是直接使用坐标轴添加更多图,如@tom's answer.

【讨论】:

你真的每天都在使用hold吗?我们一直在谈论弃用它,我想和实际使用它的人谈谈.... @tcaswell 我确实倾向于,但我认为这主要是由于我使用 MATLAB 养成的习惯。话虽如此,我实际上确实喜欢tom 提到的替代方法,但我从没想过要使用它! 另外,我认为大多数东西都默认为hold==True。如果您发现无法删除的用例,请在 GH 上提出问题 AttributeError: 'Axes3D' 对象没有属性 'hold'【参考方案3】:

只是添加到@suever 的答案,你没有理由不能创建Axes 然后在其上绘制表面和散点。那么就不用ax.hold()了:

# Create the figure
fig = plt.figure()

# Add an axes
ax = fig.add_subplot(111,projection='3d')

# plot the surface
ax.plot_surface(xx, yy, z, alpha=0.2)

# and plot the point 
ax.scatter(point2[0] , point2[1] , point2[2],  color='green')

【讨论】:

以上是关于Matplotlib - 同时绘制 3D 平面和点的主要内容,如果未能解决你的问题,请参考以下文章

绘制 3D 非正交坐标

matplotlib 中的曲面和 3d 轮廓

我想使用matplotlib制作给定z函数的3d图

在android中同时绘制剪切平面和线框

Python 使用 matplotlib绘制3D图形

使用 Python matplotlib 绘制 3d 矢量