from mpl_toolkits.mplot3d import axes3d
from matplotlib.patches import Circle
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.art3d as art3d
import numpy as np
R, r = 15, 5
def get_x(phi, theta):
global r, R
return (R + r * np.cos(phi)) * np.cos(theta)
def get_y(phi, theta):
global r, R
return (R + r * np.cos(phi)) * np.sin(theta)
def get_z(phi, theta):
global r
return r * np.sin(phi)
if __name__ == "__main__":
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111, projection='3d')
ph = th = np.linspace (-np.pi, np.pi,30)
phi, theta = np.meshgrid (ph, th)
x = np.array([get_x(p,t) for p,t in zip(np.ravel(phi), np.ravel(theta))])
X = x.reshape(phi.shape)
y = np.array([get_y(p,t) for p,t in zip(np.ravel(phi), np.ravel(theta))])
Y = y.reshape(phi.shape)
z = np.array([get_z(p,t) for p,t in zip(np.ravel(phi), np.ravel(theta))])
Z = z.reshape(phi.shape)
C1 = Circle( (R,0), radius=r, fc='none', ec='red')
C2 = Circle( (0,0), radius=R, fc='none', ec='magenta')
ax.plot_wireframe(X, Y, Z, color='#CCCCCC')
ax.add_patch(C1)
ax.add_patch(C2)
art3d.pathpatch_2d_to_3d(C1, z=0, zdir='y')
art3d.pathpatch_2d_to_3d(C2, z=r, zdir='z')
ax.set_xlim3d(-20,20)
ax.set_ylim3d(-20,20)
ax.set_zlim3d(-20,20)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_axis_off()
ax.view_init(elev=30, azim=-45)
plt.show()
plt.savefig('torus.svg', bbox_inches='tight', pad_inches=.15, \
bbox_extra_artists=[C1,C2], transparent='true')