我可以从函数列表中绘制吗?

Can I plot from a list of functions?

我正在尝试编写一个程序,给定单位球外接的四面体的一个顶点,找到其他 3 个顶点,它们在 S^3 中的纤维以及这些纤维在 R^3 上的立体投影。所以这些纤维中的每一个及其立体投影都是 theta 的函数(实际上它们是圆),我想绘制这些圆。

我是否必须明确写出每个函数?我正在尝试使用 'lambda' 关键字来使用函数列表,但它没有像我希望的那样工作。我是 python 的新手,所以任何帮助都会很棒。

我的代码:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from collections import defaultdict
from _future_ import division 


# Tetrahedron

#  given the first vertex of the tetrahedron, calculate the 
#  coordinates of the other 3 vertices
v1 = np.array([np.sqrt(2.)/3., -1/3., np.sqrt(2./3.)], dtype = float) 

# find two unit vectors orthogonal to v_1
x=np.array([1.,0.,0.])
b1=np.cross(v1,x)
u1=b1/np.linalg.norm(b1)
b2=np.cross(v1,b1)
u2=b2/np.linalg.norm(b2)

# find other vertices
v2=-1/3.*v1+np.sqrt(8)/3.*u1
v3=-1/3.*v1+np.sqrt(2)/3.*(-1.*u1+np.sqrt(3.)*u2)
v4=-1/3.*v1+np.sqrt(2)/3.*(-1.*u1-np.sqrt(3.)*u2)
V=np.array([v1,v2,v3,v4])

# Find fibers of each vertex (S^3)
k=[]

for i in range(4):
  a.append(lambda the, z=i:k*(1.+V[z][2])*np.cos(the))
b=[]             # 2nd coord.
for i in range(4):
  b.append(lambda the, z=i:k*(V[z][0]*np.sin(the)-\
    V[z][1]*np.cos(the)))
c=[]             # 3rd coord.
for i in range(4):
  c.append(lambda the, z=i:k*(V[z][0]*np.cos(the)+\
        V[z][1]*np.sin(the)))
d=[]             # 4th coord.
for i in range(4):
  d.append(lambda the, z=i:k*(np.sin(the)+V[z][2]*np.sin(the)))

# Find stereographic projection of fibers (R^3)
q=[]            
for i in range(4):
  q.append(lambda the, z=i:b[z]/(1.-a[z]))
r=[]            
for i in range(4):
  r.append(lambda the, z=i:c[z]/(1.-a[z]))     
s=[]            
for i in range(4):
  s.append(lambda the, z=i:d[z]/(1.-a[z]))

现在,我想创建一个 3d 图。我写了

fig = plt.figure()
ax = fig.gca(projection='3d')
the = np.linspace(0, 2*np.pi, 100)
q=b[0]/(1-a[0])
r=c[0]/(1-a[0])
s=d[0]/(1-a[0])
ax.plot(q,r,s)
plt.show()

但我得到 "TypeError: unsupported operand type(s) for -: 'int' and 'function'"

更新:改变了我的方法。这是我的新代码。我仍然想知道如何遍历顶点进行绘图,这样我就没有太多的代码重用。

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

# Tetrahedron

#  given the first vertex of the tetrahedron, calculate the 
#  coordinates of the other 3 vertices
v1 = np.array([np.sqrt(2.)/3., -1/3., np.sqrt(2./3.)], dtype = float) 

# find two unit vectors orthogonal to v_1
x=np.array([1.,0.,0.])
b1=np.cross(v1,x)
u1=b1/np.linalg.norm(b1)
b2=np.cross(v1,b1)
u2=b2/np.linalg.norm(b2)

# find other vertices
v2=-1/3.*v1+np.sqrt(8)/3.*u1
v3=-1/3.*v1+np.sqrt(2)/3.*(-1.*u1+np.sqrt(3.)*u2)
v4=-1/3.*v1+np.sqrt(2)/3.*(-1.*u1-np.sqrt(3.)*u2)
V=np.array([v1,v2,v3,v4])

k=[]
for i in range(4):
  k.append(1./(2.+2.*V[i][2]))

fig = plt.figure()
ax = fig.gca(projection='3d')
the = np.linspace(0, 2*np.pi, 100)
q0=k[0]*(V[0][0]*np.sin(the)-V[0][1]*np.cos(the))/\
(1.-k[0]*(1.+V[0][2])*np.cos(the))
r0=k[0]*(V[0][0]*np.cos(the)+V[0][1]*np.sin(the))/\
(1.-k[0]*(1.+V[0][2])*np.cos(the))
s0=k[0]*(1.+V[0][2])*np.sin(the)/\
(1.-k[0]*(1.+V[0][2])*np.cos(the))
ax.plot(q0,r0,s0,'b')

q1=k[1]*(V[1][0]*np.sin(the)-V[1][1]*np.cos(the))/\
(1.-k[1]*(1.+V[1][2])*np.cos(the))
r1=k[1]*(V[1][0]*np.cos(the)+V[1][1]*np.sin(the))/\
(1.-k[1]*(1.+V[1][2])*np.cos(the))
s1=k[1]*(1.+V[1][2])*np.sin(the)/\
(1.-k[1]*(1.+V[1][2])*np.cos(the))
ax.plot(q1,r1,s1,'r')

q2=k[2]*(V[2][0]*np.sin(the)-V[2][1]*np.cos(the))/\
(1.-k[2]*(1.+V[2][2])*np.cos(the))
r2=k[2]*(V[2][0]*np.cos(the)+V[2][1]*np.sin(the))/\
(1.-k[2]*(1.+V[2][2])*np.cos(the))
s2=k[2]*(1.+V[2][2])*np.sin(the)/\
(1.-k[2]*(1.+V[2][2])*np.cos(the))
ax.plot(q2,r2,s2,'g')

q3=k[3]*(V[3][0]*np.sin(the)-V[3][1]*np.cos(the))/\
(1.-k[3]*(1.+V[3][2])*np.cos(the))
r3=k[3]*(V[3][0]*np.cos(the)+V[3][1]*np.sin(the))/\
(1.-k[3]*(1.+V[3][2])*np.cos(the))
s3=k[3]*(1.+V[3][2])*np.sin(the)/\
(1.-k[3]*(1.+V[3][2])*np.cos(the))
ax.plot(q3,r3,s3,'m')

plt.show()

您可以通过压缩 k 和 V 列表来遍历顶点。如果您想要图例或不同的颜色循环,则必须将它们添加到对 zip 的调用中。

for k0, V0 in zip(k, V):
    q=k0*(V0[0]*np.sin(the)-V0[1]*np.cos(the))/\
      (1.-k0*(1.+V0[2])*np.cos(the))
    r=k0*(V0[0]*np.cos(the)+V0[1]*np.sin(the))/\
      (1.-k0*(1.+V0[2])*np.cos(the))
    s=k0*(1.+V0[2])*np.sin(the)/\
      (1.-k0*(1.+V0[2])*np.cos(the))
    ax.plot(q,r,s,)