Search code examples
numpymatplotlibsurface

How do I create a surface plot with matplotlib of a closed loop revolve about an axis given coordinate data of the 2D profile?


  • I have the closed loop stored as a two column by N row numpy array.

  • The last row of the array is the same as the first row, implying that it is, indeed, a closed loop.

  • The number of angular divisions in the rotation (as in, "slices of pie" so to speak) ought be set by a variable called 'angsteps'

  • The profile in question is plotted in the x-y coordinate plane, and is rotated about the 'x-axis'.

  • You can find the profile in question plotted here. https://i.sstatic.net/U6bHP.png

I apologize for the lack of code, but the profile data has so many interdependencies that I can't post the code that generates it without basically taking a shortcut to plugging the github page for it.

a downsampled version of the curve data looks like this.

    bulkmat =         [[  5.2          0.        ]
     [  0.381        0.        ]
     [  0.381        3.164     ]
     [  2.           3.164     ]
     [  2.           4.1       ]
     [  3.78         4.1       ]
     [  3.78         6.477     ]
     [  1.898        6.477     ]
     [  1.898        7.        ]
     [  3.18         7.        ]
     [  3.18         9.6       ]
     [  1.898        9.6       ]
     [  1.898        9.6       ]
     [  2.31987929  12.42620027]
     [  3.4801454   15.24663923]
     [  5.22074074  17.97407407]
     [  7.38360768  20.521262  ]
     [  9.81068861  22.80096022]
     [ 12.34392593  24.72592593]
     [ 14.825262    26.20891632]
     [ 17.09663923  27.16268861]
     [ 19.          27.5       ]
     [ 19.          27.5       ]
     [ 19.62962963  27.44718793]
     [ 20.18518519  27.29972565]
     [ 20.66666667  27.07407407]
     [ 21.07407407  26.7866941 ]
     [ 21.40740741  26.45404664]
     [ 21.66666667  26.09259259]
     [ 21.85185185  25.71879287]
     [ 21.96296296  25.34910837]
     [ 22.          25.        ]
     [ 22.          25.        ]
     [ 21.12125862  24.17043472]
     [ 18.91060645  23.59946824]
     [ 15.97201646  22.9218107 ]
     [ 12.84280513  21.85346069]
     [  9.96762011  20.14089993]
     [  7.67242798  17.51028807]
     [  6.13850192  13.61665735]
     [  5.37640942   7.99310742]
     [  5.2          0.        ]]

Solution

  • The following would be an example of a solid of revolution plotted around the z axis. As input we take some points and then create the necessary 2D arrays from them.

    import numpy as np
    import matplotlib.pyplot as plt
    import mpl_toolkits.mplot3d.axes3d as axes3d
    
    # input xy coordinates
    xy = np.array([[1,0],[2,1],[2,2],[1,1.5],[1,0]])
    # radial component is x values of input
    r = xy[:,0]
    # angular component is one revolution of 60 steps
    phi = np.linspace(0, 2*np.pi, 60)
    # create grid
    R,Phi = np.meshgrid(r,phi)
    # transform to cartesian coordinates
    X = R*np.cos(Phi)
    Y = R*np.sin(Phi)
    # Z values are y values, repeated 60 times
    Z = np.tile(xy[:,1],len(Y)).reshape(Y.shape)
    
    
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1, projection='3d')
    ax2 = fig.add_axes([0.05,0.7,0.15,.2])
    ax2.plot(xy[:,0],xy[:,1], color="k")
    
    ax.plot_surface(X, Y, Z, alpha=0.5, color='gold', rstride=1, cstride=1)
    
    plt.show()
    

    enter image description here