主要的想法是这样的: 绿色圆圈分为2个,共有8组(这就是为什么是8轴)。当任何蓝色圆圈通过绿色圆圈时,在相应的轴上绘制相应时间内的垂直线。我不知道如何制作这个。欢迎任何想法:) 映入眼帘! 代码:
circ = np.linspace(0,360,360)
circ*=2*np.pi/360
ra = np.empty(360)
wheel_position=[]
ra.fill(28120/2)
r=np.full((1,10*2),28120/2)
Ru=180-np.array([24,63,102,141,181.5,219,258,297,336,360])
Ru_pos=[]
rtm_pos= np.array([22.5,67.5,112.5,157.5,202.5,247.5,292.5,337.5])
rw=np.empty(16)
rw.fill(28120/2)
for i in rtm_pos:
wheel_position.append([i-2.3,i+2.3])
wheel_position=np.array(wheel_position)
wheel_position=2*np.pi/360*np.ravel(wheel_position)
for i in Ru:
Ru_pos.append([i-0.51,i+0.51])
Ru_pos=np.ravel(Ru_pos)
Ru_pos=2*np.pi/360*Ru_pos
def simData():
t_max=360
theta0=Ru_pos
theta=np.array([0,0])
t=0
dt=0.5
vel=2*np.pi/360
while t<t_max:
theta=theta0+vel*t
t=t+dt
yield theta, t
def simPoints(simData):
theta, t = simData[0], simData[1]
time_text.set_text(time_template%(t))
line.set_data(theta,r)
fig = plt.figure()
ax1.set_rmax(28120/2+1550)
ax1.grid(True)
ax1 = fig.add_subplot(121, projection='polar')
line, = ax1.plot([], [], 'bo', ms=3, zorder=2)
time_template = 'Time = %.1f s'
time_text = ax1.text(0.05, 0.9, '', transform=ax.transAxes)
ax1.set_ylim(0, 28120/2+5000)
ax1.plot(circ,ra, color='r', linestyle='-',zorder=1,lw=1)
ax1.plot(wheel_position,rw,'bo',ms=4.6,zorder=3,color='g')
ani = animation.FuncAnimation(fig, simPoints, simData, blit=False,\
interval=1, repeat=True)
plt.show()
答案 0 :(得分:1)
主要更改将插入原始animation.FuncAnimation
之前和之前plt.show()
:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
circ = np.linspace(0,360,360)
circ *= 2*np.pi/360
ra = np.empty(360)
wheel_position=[]
ra.fill(28120/2)
r = np.full((1,10*2),28120/2)
Ru = 180 - np.array([24,63,102,141,181.5,219,258,297,336,360])
Ru_pos = []
rtm_pos = np.array([22.5,67.5,112.5,157.5,202.5,247.5,292.5,337.5])
rw = np.empty(16)
rw.fill(28120/2)
for i in rtm_pos:
wheel_position.append([i-2.3,i+2.3])
wheel_position=np.array(wheel_position)
wheel_position=2*np.pi/360*np.ravel(wheel_position)
for i in Ru:
Ru_pos.append([i-0.51,i+0.51])
Ru_pos = np.ravel(Ru_pos)
Ru_pos = 2*np.pi/360*Ru_pos
def simData():
t_max = 360
theta0 = Ru_pos
theta = np.array([0,0])
t = 0
dt = 0.5
vel = 2*np.pi/360
while t<t_max:
theta=theta0+vel*t
t=t+dt
yield theta, t
# renamed parameter to avoid confusion with the function
def simPoints(data):
theta, t = data[0], data[1]
time_text.set_text(time_template%(t))
line.set_data(theta,r)
# Number of subplots needed for green pairs
nplots = int(len(wheel_position)/2)
fig = plt.figure()
ax1 = plt.subplot2grid((nplots,2),(0,0), rowspan=nplots, projection='polar')
ax1.set_rmax(28120/2+1550)
ax1.grid(True)
line, = ax1.plot([], [], 'bo', ms=3, zorder=2)
time_template = 'Time = %.1f s'
time_text = ax1.text(0.05, 0.9, '', transform=ax1.transAxes)
ax1.set_ylim(0, 28120/2+5000)
# red circle
ax1.plot(circ,ra, color='r', linestyle='-',zorder=1,lw=1)
# green dots
green_line, = ax1.plot(wheel_position,rw,'bo',ms=4.6,zorder=3,color='g')
green_dots = green_line.get_data()[0]
green_dots = np.reshape(green_dots, (int(len(green_dots)/2),2))
ani1 = animation.FuncAnimation(fig, simPoints, simData, blit=False,\
interval=1, repeat=True)
# Used to check if we should mark an intersection for a given tick
# Update this with your preferred distance function
def check_intersect(pt1, pt2, tolerance=0.05):
return np.linalg.norm(pt1-pt2) < tolerance
def greenFunc(*args):
t = args[0]
affected_plots = []
for n in range(nplots):
ax = green_plots[n]
blue_dots = line.get_data()[0]
if len(blue_dots) < 2: # still initializing
return ax,
blue_dots = np.reshape(blue_dots, (int(len(blue_dots)/2),2))
is_intersect = False
for dot in blue_dots:
if check_intersect(dot, green_dots[n]):
is_intersect = True
if is_intersect:
ax.plot([t,t], [-1,1], color='k')
affected_plots.append(ax)
return affected_plots
# Create the 8 subplots
green_plots = []
for i in range(nplots):
if i == 0:
ax = plt.subplot2grid((nplots,2),(i,1))
else:
ax = plt.subplot2grid((nplots,2),(i,1), sharex=green_plots[0], sharey=green_plots[0])
# Hide x labels on all but last
if i < nplots-1:
plt.setp(ax.get_xticklabels(), visible=False)
green_plots.append(ax)
# Add animation for intersections with green circles
ani = animation.FuncAnimation(fig, greenFunc, \
blit=False, interval=1, repeat=True)
plt.show()
这引入了两个新功能:
check_intersect
根据给定公差范围内的欧几里德距离决定是否应将两个点计为交叉(从而绘制一条线)。公差是必要的,因为位置是以离散的间隔计算的(尝试零容差 - 它永远不会是完全匹配)。您可能希望根据需要调整等式和公差。
greenFunc
(我知道,有创意)循环遍历所有子图并检查是否画线。
其余的只是创建子图并添加一个调用greenFunc
的动画。
让它运行一段时间后,我得到了结果:
更改标签大小和位置留给读者练习;)