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()

The 3d-plot should look like this:

解决方案

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

更多推荐

python 3d绘图旋转,Python:如何围绕z轴旋转曲面并绘制3d图?