jonboy
jonboy

Reputation: 372

Animate vertical line with scatter and circle - matplotlib

I am trying to animate a vertical line along with a scatter and circle. I can get the scatter and circle working but not the vertical line. If possible, I'd also like the vertical line to not plot outside the radius of the circle. I can follow up on this though.

I'll comment out the function in animate in regards to the line so it runs. But when applying the animated line, it doesn't work.

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import animation

fig, ax = plt.subplots(figsize = (8,8))
ax.set_xlim(-20,20)
ax.set_ylim(-20,20)
ax.grid(False)

df = pd.DataFrame({   
    'Time' : [1,1,1,1,2,2,2,2,3,3,3,3],             
    'X2' : [0,0,0,0,-1,-1,-1,-1,0,0,0,0],
    'Y2' : [0,0,0,0,1,1,1,1,1,1,1,1],                    
    })

moving_x = np.array(df.groupby(['Time'])['X2'].apply(list))
moving_y = np.array(df.groupby(['Time'])['Y2'].apply(list))

# scatter moving
moving_point = ax.scatter(moving_x[0], moving_y[0], c = 'black', marker = 'x')

# Array of immediate congestion radius coordinates
radius = df.drop_duplicates(subset = ['Time','X2', 'Y2'])[['X2', 'Y2']].values

# Plot immediate congestion radius
circle = plt.Circle(radius[0], 10, color = 'black', fill = False)

# Add radius to plot
ax.add_patch(circle)

t = df.drop_duplicates(subset = ['Time','X2'])[['X2']].values

line1 = ax.axvline(t[0], ls = '--', color = 'black', lw = 1, zorder = 10)

def animate(i) :

    circle.center = (radius[i,0], radius[i,1])

    # Animate vertical line
    #line1.set_data([i, i],[0,t])
    
    moving_point.set_offsets(np.c_[moving_x[0+i], moving_y[0+i]])


ani = animation.FuncAnimation(fig, animate,  np.arange(0,2), blit = False)

Upvotes: 1

Views: 450

Answers (1)

Sameeresque
Sameeresque

Reputation: 2602

You want to set blit=True so that you don't have to redraw things since the axes have not changed. I have also avoided the use of axvline as shown below:

enter image description here

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import animation

fig, ax = plt.subplots(figsize = (8,8))
ax.set_xlim(-20,20)
ax.set_ylim(-20,20)
ax.grid(False)

df = pd.DataFrame({   
    'Time' : [1,1,1,1,2,2,2,2,3,3,3,3],             
    'X2' : [0,0,0,0,-1,-1,-1,-1,0,0,0,0],
    'Y2' : [0,0,0,0,1,1,1,1,1,1,1,1],                    
    })

moving_x = np.array(df.groupby(['Time'])['X2'].apply(list))
moving_y = np.array(df.groupby(['Time'])['Y2'].apply(list))

# scatter moving
moving_point = ax.scatter(moving_x[0], moving_y[0], c = 'black', marker = 'x')

# Array of immediate congestion radius coordinates
radius = df.drop_duplicates(subset = ['Time','X2', 'Y2'])[['X2', 'Y2']].values

# Plot immediate congestion radius
circle = plt.Circle(radius[0], 10, color = 'black', fill = False)

# Add radius to plot
ax.add_patch(circle)

t = df.drop_duplicates(subset = ['Time','X2'])[['X2']].values

#line1 = ax.axvline(t[0], ls = '--', color = 'black', lw = 1, zorder = 10)
line1, = ax.plot([], [], ls='--', color='black',lw=1, zorder=10,animated=True)
def animate(i) :
    circle.center = (radius[i,0], radius[i,1])

    # Animate vertical line
    line1.set_data([radius[i,0], radius[i,0]],[radius[i,1]-10,radius[i,1]+10])
    
    moving_point.set_offsets(np.c_[moving_x[0+i], moving_y[0+i]])
    return circle, line1, moving_point

ani = animation.FuncAnimation(fig, animate,  np.arange(0,2), blit = True)
plt.show()

Upvotes: 2

Related Questions