【问题标题】:Plotting a 3D surface from Cartesian coordinates (either matplotlib or pyplot)从笛卡尔坐标绘制 3D 表面(matplotlib 或 pyplot)
【发布时间】:2021-08-15 12:56:57
【问题描述】:

我有一个数据框:

  surfacex surfacey surfacez
0   -0.50   0.00    0.00
1   -0.48   -0.14   0.00
2   -0.48   -0.12   -0.06
3   -0.48   -0.12   0.06
4   -0.48   -0.10   -0.08
... ... ... ...
3897    0.48    0.10    0.08
3898    0.48    0.12    -0.06
3899    0.48    0.12    0.06
3900    0.48    0.14    0.00
3901    0.50    0.00    0.00

每行代表一个 3D 点。我想绘制一个限定这些点的表面。在这种情况下,这些点都位于球体的表面上,因此我想绘制一个球面。目前这是我正在尝试的:

import numpy as np
import plotly.graph_objects as go
X=df['surfacex'].values
Y=df['surfacey'].values
Z=df['surfacez'].values
trace= go.Surface(x=np.reshape(X,(1951,2)),y=np.reshape(Y,(1951,2)),z=np.reshape(Z,(1951,2)))
#I am reshaping as online tells me it needs to be a 2D array, and my df is of length 3902
fig2=go.Figure(data=[trace])
fig2.show()

但是,结果图如下所示:

这显然不是我想要的。我想要的是类似于:

我怎样才能达到想要的情节? Matplotlib 或 plotly 解决方案都可以

谢谢

【问题讨论】:

    标签: python matplotlib plot


    【解决方案1】:

    使用 Maplotlib,计算数据点的 convex hull,然后

    第 1 步:创建一些测试数据(球内的随机点,使用 this link,第 6.08 节):

    import numpy as np
    from math import pi
    
    n=500 #number of data points
    z=np.random.uniform(low=-1.0, high=1.0, size=n)
    t=np.random.uniform(low=0.0, high=2*pi, size=n)
    r=np.sqrt(1-z*z)
    x=r*np.cos(t)
    y=r*np.sin(t)
    sphere=np.vstack([x,y,z]).T
    

    第 2 步:获取位于球体表面上的所有点:

    from scipy.spatial import ConvexHull
    hull = ConvexHull(sphere)
    surface=sphere[hull.vertices]
    

    第 3 步:使用表面上的点创建 3d 散点图:

    import matplotlib.pyplot as plt
    
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    ax.set_box_aspect((1,1,1))
    ax.scatter(surface[:,0], surface[:,1], surface[:,2])
    

    第 4 步:使用Delaunay triangulation 计算并绘制代表曲面的三角形。绘制曲面单个元素的方法取自this answer

    from scipy.spatial import Delaunay
    deln = Delaunay(surface) 
    
    def plot_tri_simple(ax, points, tri):
        for tr in tri.simplices:
            pts = points[tr, :]
            ax.plot3D(pts[[0,1],0], pts[[0,1],1], pts[[0,1],2], color='g', lw='0.1')
            ax.plot3D(pts[[0,2],0], pts[[0,2],1], pts[[0,2],2], color='g', lw='0.1')
            ax.plot3D(pts[[0,3],0], pts[[0,3],1], pts[[0,3],2], color='g', lw='0.1')
            ax.plot3D(pts[[1,2],0], pts[[1,2],1], pts[[1,2],2], color='g', lw='0.1')
            ax.plot3D(pts[[1,3],0], pts[[1,3],1], pts[[1,3],2], color='g', lw='0.1')
            ax.plot3D(pts[[2,3],0], pts[[2,3],1], pts[[2,3],2], color='g', lw='0.1')
    
    
    plot_tri_simple(ax, surface, deln)
    

    【讨论】:

    • 您好,感谢您的回复。我只进行了一项更改以获得所需的输出,即从凸包顶点绘制 3d 网格而不是散点图
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多