如何解决使用低于零的“负”Z 轴构建 3D 绘图
我们正在开展一个要构建 3D 绘图的项目。 Python 是我们的主要语言,因此自然选择使用 matplotlib
作为我们的绘图库。各种教程(here、here 和 here)教我们如何使用 matplotlib 的 mplot3d
功能执行 3D 绘图。因此,各种 StackOverflow 答案帮助我们将每个轴的原点移动到不同的位置(here 和 here)。
然而,在搜索了几个小时之后,我们很难找到下一个问题的答案。我们希望 Z 轴有正负两面(见下图,橙色部分)。这意味着 Z>0 的数据点高于原点,而 Z
在社区的大力帮助下,我们找到了一个展示我想要的东西的最小示例。我使用的代码是:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10,10))
ax = fig.gca(projection='3d')
# Some settings
sn = 2 #limits in x,y,z
n = 50 #number of sample points
x1,x2 = 0,sn
y1,y2 = 0,sn
z1,z2 = -sn,sn
# Data for points
xs = (x2 - x1)*np.random.rand(n) + x1
ys = (y2 - y1)*np.random.rand(n) + y1
zs = (z2 - z1)*np.random.rand(n) + z1
# Points with z >= 0,plotted in green
ax.scatter(xs[zs>=0],ys[zs>=0],zs[zs>=0],color='green')
# Points with z < 0,plotted in red
ax.scatter(xs[zs<0],ys[zs<0],zs[zs<0],color='red')
# Data for plotting plane x|y|z=0 within the domain
tmp = np.linspace(0,sn,8)
x,y = np.meshgrid(tmp,tmp)
z = 0*x
# Plot grid lines
ax.plot([0,sn],[0,0],color='black')
ax.plot([0,[-sn,color='black')
# Maximum tick labels for X,Y,and Z (x3)
ax.plot([sn,[-.05,.02],[sn,color='black')
ax.plot([-.05,-sn],color='black')
# Label texts
ax.text(sn/2,-.2*sn,'xlabel','x',ha='center')
ax.text(0,sn/2,'ylabel','y',ha='center')
ax.text(-.1*sn,'zlabel','z',ha='center')
# Maximum limit text for X,Y and Z (x3)
ax.text(sn,-.1*sn,f'{sn}',ha='center')
ax.text(-.05*sn,-.05*sn,'0',ha='right')
ax.text(-.05*sn,-sn,f'{-sn}',ha='center')
# Set limits of the 3D display
ax.set_xlim3d([-sn,sn])
ax.set_ylim3d([-sn,sn])
ax.set_zlim3d([-sn,sn])
ax.set_axis_off()
plt.show()
结果如下图:
尽管我对结果非常满意,但这仍然是一种手动绘制轴、刻度和标签的“hacky”解决方案。如果有人有一个解决方案,我们可以在其中重新设计 mplot3d
API 中的轴,那将非常有帮助。
解决方法
(Swatchai 将此创建为社区维基):
有时,没有一些可运行的代码来播放/实验的讨论并不是获得解决方案的最佳方法。在这里我建议使用此代码以供进一步讨论。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10,10))
ax = fig.gca(projection='3d')
# Quivers for axes x,y,z from (0,0)
quiver1 = ax.quiver([0],[0],[2],colors='r')
quiver2 = ax.quiver([0],colors='g')
quiver3 = ax.quiver([0],colors='b')
# Some settings
sn = 2 #limits in x,z
n = 50 #number of sample points
x1,x2 = -sn,sn
y1,y2 = -sn,sn
z1,z2 = -sn,sn
# Data for points
xs = (x2 - x1)*np.random.rand(n) + x1
ys = (y2 - y1)*np.random.rand(n) + y1
zs = (z2 - z1)*np.random.rand(n) + z1
# Points with z >= 0,plotted in green
ax.scatter(xs[zs>=0],ys[zs>=0],zs[zs>=0],color='green')
# Points with z < 0,plotted in red
ax.scatter(xs[zs<0],ys[zs<0],zs[zs<0],color='red')
# Data for plotting plane x|y|z=0 within the domain
tmp = np.linspace(0,sn,8)
x,y = np.meshgrid(tmp,tmp)
z = 0*x
ax.plot_surface(z,x,alpha=0.15,color='red') # plot the plane x=0
ax.plot_surface(x,z,color='green') # plot the plane y=0
ax.plot_surface(x,color='blue') # plot the plane z=0
# Set limits of the 3D display
ax.set_xlim3d([-sn,sn])
ax.set_ylim3d([-sn,sn])
ax.set_zlim3d([-sn,sn])
# Set labels at the 3d box/frame
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
输出图:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。