【问题标题】:Plot surfaces on a cube在立方体上绘制曲面
【发布时间】:2015-11-05 08:52:18
【问题描述】:

我想用matplotlib 将曲面绘制成立方体。我正在尝试使用ax.plot_surface(X, Y, Z),但是我有点困惑。 XYZ 应该代表什么二维数组?

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

points = np.array([[-1, -1, -1],
                      [1, -1, -1 ],
                      [1, 1, -1],
                      [-1, 1, -1],
                      [-1, -1, 1],
                      [1, -1, 1 ],
                      [1, 1, 1],
                      [-1, 1, 1]])

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# ax.plot_surface(X, Y, Z)  # how?
ax.scatter3D(points[:, 0], points[:, 1], points[:, 2])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    立方体的每个面都是一个表面,您可以自己定义每个角,也可以使用网格:

    import numpy as np
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    
    points = np.array([[-1, -1, -1],
                          [1, -1, -1 ],
                          [1, 1, -1],
                          [-1, 1, -1],
                          [-1, -1, 1],
                          [1, -1, 1 ],
                          [1, 1, 1],
                          [-1, 1, 1]])
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    r = [-1,1]
    X, Y = np.meshgrid(r, r)
    ax.plot_surface(X,Y,1, alpha=0.5)
    ax.plot_surface(X,Y,-1, alpha=0.5)
    ax.plot_surface(X,-1,Y, alpha=0.5)
    ax.plot_surface(X,1,Y, alpha=0.5)
    ax.plot_surface(1,X,Y, alpha=0.5)
    ax.plot_surface(-1,X,Y, alpha=0.5)
    ax.scatter3D(points[:, 0], points[:, 1], points[:, 2])
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.show()
    

    X、Y 和 Z 是(相同的)二维点列表:

    >>> numpy.meshgrid([-1,1], [-1,1])
    [array([[-1,  1],
           [-1,  1]]), array([[-1, -1],
           [ 1,  1]])]
    

    【讨论】:

    • 有没有更有效的方法将 ax.plot_surface() 包裹在一个循环中?
    【解决方案2】:

    修复新的 matplotlib

    import numpy as np
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    
    points = np.array([[-1, -1, -1],
                          [1, -1, -1 ],
                          [1, 1, -1],
                          [-1, 1, -1],
                          [-1, -1, 1],
                          [1, -1, 1 ],
                          [1, 1, 1],
                          [-1, 1, 1]])
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    r = [-1,1]
    X, Y = np.meshgrid(r, r)
    one = np.ones(4).reshape(2, 2)
    ax.plot_wireframe(X,Y,one, alpha=0.5)
    ax.plot_wireframe(X,Y,-one, alpha=0.5)
    ax.plot_wireframe(X,-one,Y, alpha=0.5)
    ax.plot_wireframe(X,one,Y, alpha=0.5)
    ax.plot_wireframe(one,X,Y, alpha=0.5)
    ax.plot_wireframe(-one,X,Y, alpha=0.5)
    ax.scatter3D(points[:, 0], points[:, 1], points[:, 2])
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.show()
    

    【讨论】:

      【解决方案3】:

      要在绘制长方体时使用对plot_surface 的单个调用,可以在两个变量上参数化表面,例如使用球坐标。

      下面绘制一个边长为 a,b,c 的长方体:

      import numpy as np
      import matplotlib.pyplot as plt
      from mpl_toolkits.mplot3d import Axes3D
      
      def get_cube():   
          phi = np.arange(1,10,2)*np.pi/4
          Phi, Theta = np.meshgrid(phi, phi)
      
          x = np.cos(Phi)*np.sin(Theta)
          y = np.sin(Phi)*np.sin(Theta)
          z = np.cos(Theta)/np.sqrt(2)
          return x,y,z
      
      
      fig = plt.figure()
      ax = fig.add_subplot(111, projection='3d')
      
      a = 1
      b = 2
      c = 3
      x,y,z = get_cube()
      
      
      ax.plot_surface(x*a, y*b, z*c)
      
      ax.set_xlim(-2,2)
      ax.set_ylim(-2,2)
      ax.set_zlim(-2,2)
      plt.show()
      


      另见Representing voxels with matplotlib

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-20
        • 2022-11-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多