【问题标题】:Add cylinder to plot将圆柱体添加到绘图
【发布时间】:2014-11-18 07:49:54
【问题描述】:

我想在我的 3D 散点图中添加一个透明圆柱体。我该怎么做?

这是我用来制作情节的代码:

fig = plt.figure(2, figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')

ax.scatter(X, Y, Z, c=Z,cmap=plt.cm.Paired)
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
plt.xticks()

【问题讨论】:

    标签: python matplotlib plot


    【解决方案1】:

    今天我必须在我的项目中做同样的事情,在结果中添加一个透明圆柱体。这是我最终得到的代码。所以分享给大家,仅供学习

    import numpy as np
    
    def data_for_cylinder_along_z(center_x,center_y,radius,height_z):
        z = np.linspace(0, height_z, 50)
        theta = np.linspace(0, 2*np.pi, 50)
        theta_grid, z_grid=np.meshgrid(theta, z)
        x_grid = radius*np.cos(theta_grid) + center_x
        y_grid = radius*np.sin(theta_grid) + center_y
        return x_grid,y_grid,z_grid
    
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    
    Xc,Yc,Zc = data_for_cylinder_along_z(0.2,0.2,0.05,0.1)
    ax.plot_surface(Xc, Yc, Zc, alpha=0.5)
    
    plt.show()
    

    你会得到这个美丽的身影。

    【讨论】:

    • +1,其他解决方案使用笛卡尔坐标将 Y 作为 X 的函数,这会导致曲面中的点分布不均匀,更重要的是,在确定所有边缘时可能会导致问题圆柱体(由于数值近似,您最终可能会得到 nan 值)。此解决方案适用于所有情况
    【解决方案2】:

    一种可能的方法是使用plot_surface。调整给定的解决方案in this blog post 然后有

    import matplotlib.pyplot as plt
    import numpy as np
    from mpl_toolkits.mplot3d import Axes3D
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    
    # Scatter graph
    N = 100
    X = np.random.uniform(-1, 1, N)
    Y = np.random.uniform(-1, 1, N)
    Z = np.random.uniform(-2, 2, N)
    ax.scatter(X, Y, Z)
    
    # Cylinder
    x=np.linspace(-1, 1, 100)
    z=np.linspace(-2, 2, 100)
    Xc, Zc=np.meshgrid(x, z)
    Yc = np.sqrt(1-Xc**2)
    
    # Draw parameters
    rstride = 20
    cstride = 10
    ax.plot_surface(Xc, Yc, Zc, alpha=0.2, rstride=rstride, cstride=cstride)
    ax.plot_surface(Xc, -Yc, Zc, alpha=0.2, rstride=rstride, cstride=cstride)
    
    ax.set_xlabel("X")
    ax.set_ylabel("Y")
    ax.set_zlabel("Z")
    plt.show()
    

    我已经添加了一些表面的最小配置,更好的可以通过咨询docs来实现。

    【讨论】:

      【解决方案3】:

      我改进了@Greg 的答案,并制作了一个带有顶面和底面的实心 3D 圆柱体,并重写了方程式,以便您可以在 x、y 和 z 中进行平移

      from mpl_toolkits.mplot3d import Axes3D
      import mpl_toolkits.mplot3d.art3d as art3d
      import matplotlib.pyplot as plt
      import numpy as np
      from matplotlib.patches import Circle
      
      def plot_3D_cylinder(radius, height, elevation=0, resolution=100, color='r', x_center = 0, y_center = 0):
          fig=plt.figure()
          ax = Axes3D(fig, azim=30, elev=30)
      
          x = np.linspace(x_center-radius, x_center+radius, resolution)
          z = np.linspace(elevation, elevation+height, resolution)
          X, Z = np.meshgrid(x, z)
      
          Y = np.sqrt(radius**2 - (X - x_center)**2) + y_center # Pythagorean theorem
      
          ax.plot_surface(X, Y, Z, linewidth=0, color=color)
          ax.plot_surface(X, (2*y_center-Y), Z, linewidth=0, color=color)
      
          floor = Circle((x_center, y_center), radius, color=color)
          ax.add_patch(floor)
          art3d.pathpatch_2d_to_3d(floor, z=elevation, zdir="z")
      
          ceiling = Circle((x_center, y_center), radius, color=color)
          ax.add_patch(ceiling)
          art3d.pathpatch_2d_to_3d(ceiling, z=elevation+height, zdir="z")
      
          ax.set_xlabel('x-axis')
          ax.set_ylabel('y-axis')
          ax.set_zlabel('z-axis')
      
          plt.show()
      
      # params
      radius = 3
      height = 10
      elevation = -5
      resolution = 100
      color = 'r'
      x_center = 3
      y_center = -2
      
      plot_3D_cylinder(radius, height, elevation=elevation, resolution=resolution, color=color, x_center=x_center, y_center=y_center)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-04
        相关资源
        最近更新 更多