2016-08-22 26 views
0

IM製作與matplotlib和Python動畫的條件動畫情節,動畫的樣子: Animation與matplotlib

我想要做的是有更多的動畫擴展這個情節,我要完成的下一圖: enter image description here

的主要思想是: 綠色圓圈在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

你的代碼,就是不運行 - 我必須添加import語句,移動'ax1 = ...'行,並將錯字修復到'ax.transAxes'中。你已經有了右邊8個子圖的代碼嗎?這對於包含也是有用的。 – whrrgarbl

回答

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決定是否不是兩個根據給定內的歐幾里得距離,點應該被視爲相交(並且因此畫一條線) n寬容。公差是必要的,因爲位置是以離散的間隔計算的(嘗試零容忍 - 它絕不會完全匹配)。您可能想根據您的需求調整公式和容差。

  • greenFunc(我知道,富有創造性)循環遍歷所有的小區,並檢查是否繪製一條線。

其餘的只是創建子圖,並添加了一個動畫,調用greenFunc

讓它跑了一會兒後,我得到的結果是:

Resulting plot

更改標籤的大小和位置就留給讀者做練習;)