Python: How to revolve a surface around z axis and make a 3d plot?
Question: I want to get 2d and 3d plots as shown below.  
The equation of the curve is given.  
How can we do so in python?  
I know there may be duplicates but at the time of posting I could not fine any
useful posts.

My initial attempt is like this:

    
    
    # Imports
    import numpy as np
    import matplotlib.pyplot as plt
    
    
    # to plot the surface rho = b*cosh(z/b) with rho^2 = r^2 + b^2
    z = np.arange(-3, 3, 0.01)
    rho = np.cosh(z)  # take constant b = 1
    
    plt.plot(rho,z)
    plt.show()
    

Some related links are following:  
[Rotate around z-axis only in
plotly](http://stackoverflow.com/questions/27677556/rotate-around-z-axis-only-
in-plotly)

The 3d-plot should look like this:  
[![enter image description
here](http://i.stack.imgur.com/u3EIn.png)](http://i.stack.imgur.com/u3EIn.png)


Answer: Ok so I think you are really asking to revolve a 2d curve around an axis to
create a surface. I come from a CAD background so that is how i explain
things. and I am not the greatest at math so forgive any clunky terminology.
Unfortunately you have to do the rest of the math to get all the points for
the mesh.

Heres your code:

    
    
    #import for 3d
    from mpl_toolkits.mplot3d import Axes3D
    
    import numpy as np
    import matplotlib.pyplot as plt
    

change arange to linspace which captures the endpoint otherwise arange will be
missing the 3.0 at the end of the array:

    
    
    z = np.linspace(-3, 3, 600)
    rho = np.cosh(z)  # take constant b = 1
    

since rho is your radius at every z height we need to calculate x,y points
around that radius. and before that we have to figure out at what positions on
that radius to get x,y co-ordinates:

    
    
    #steps around circle from 0 to 2*pi(360degrees)
    #reshape at the end is to be able to use np.dot properly
    revolve_steps = np.linspace(0, np.pi*2, 600).reshape(1,600)
    

the Trig way of getting points around a circle is:  
x = r*cos(theta)  
y = r*sin(theta)

for you r is your rho, and theta is revolve_steps

by using np.dot to do matrix multiplication you get a 2d array back where the
rows of x's and y's will correspond to the z's

    
    
    theta = revolve_steps
    #convert rho to a column vector
    rho_column = rho.reshape(600,1)
    x = rho_column.dot(np.cos(theta))
    y = rho_column.dot(np.sin(theta))
    # expand z into a 2d array that matches dimensions of x and y arrays..
    # i used np.meshgrid
    zs, rs = np.meshgrid(z, rho)
    
    #plotting
    fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
    fig.tight_layout(pad = 0.0)
    #transpose zs or you get a helix not a revolve.
    # you could add rstride = int or cstride = int kwargs to control the mesh density
    ax.plot_surface(x, y, zs.T, color = 'white', shade = False)
    #view orientation
    ax.elev = 30 #30 degrees for a typical isometric view
    ax.azim = 30
    #turn off the axes to closely mimic picture in original question
    ax.set_axis_off()
    plt.show()
    
    #ps 600x600x600 pts takes a bit of time to render
    

I am not sure if it's been fixed in latest version of matplotlib but the
setting the aspect ratio of 3d plots with:

    
    
    ax.set_aspect('equal')
    

has not worked very well. you can find solutions at [this stack overflow
question](http://stackoverflow.com/questions/13685386/matplotlib-equal-unit-
length-with-equal-aspect-ratio-z-axis-is-not-equal-to)

