I'm new to python's matplotlib, and i want to animate a 1x1 square that moves diagonally across a grid space. I have written this bit of code that almost does what i want it to do, but the previous positions of the rectangle are still visible.
import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np
from matplotlib.patches import Rectangle
moving_block = [[0,0],[1,1],[2,2],[3,3],[4,4],[5,5]]
fig, ax = plt.subplots()
#set gridlines and lines every one unit
ax.grid(which='both')
ax.axis([0,5,0,5])
rectangle = Rectangle(moving_block[0], 1,1)
ax.add_patch(rectangle)
def animate(i):
ax.add_patch(Rectangle(moving_block[i], 1,1))
ani = matplotlib.animation.FuncAnimation(fig, animate,
frames=len(moving_block), interval=300, repeat=True)
plt.show()
How can i make only the current rectangle visible? Should i be using something other than this ax.add_patch(Rectangle) function?
Added cleaning "ax", at each iteration in the function "animate".
If you are satisfied with the answer, do not forget to vote for it :-)
import matplotlib.pyplot as plt
import matplotlib.animation
from matplotlib.patches import Rectangle
moving_block = [[0,0],[1,1],[2,2],[3,3],[4,4],[5,5]]
fig, ax = plt.subplots()
#set gridlines and lines every one unit
ax.grid(which='both')
ax.axis([0, 5, 0, 5])
rectangle = Rectangle(moving_block[0], 1,1)
ax.add_patch(rectangle)
def animate(i):
ax.clear()
ax.axis([0, 5, 0, 5])
ax.grid(which='both')
ax.add_patch(Rectangle(moving_block[i], 1,1))
ani = matplotlib.animation.FuncAnimation(fig, animate,
frames=len(moving_block), interval=300, repeat=True)
plt.show()
Related
I want to plot a moving dot from left to right. Here's my code:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
Acc_11 = [0,1,2,3,4,5,6,7,8]
Acc_12 = [4,4,4,4,4,4,4,4,4]
fig = plt.figure()
axes = fig.add_subplot(111, autoscale_on=False)
axes.set_xlim(min(Acc_11), max(Acc_11))
axes.set_ylim(0, 8)
point, = axes.plot([Acc_11[0]],[Acc_12[0]], 'go')
def ani(coords):
point.set_data([coords[0]],[coords[1]])
return point,
def frames():
for acc_11_pos, acc_12_pos in zip(Acc_11, Acc_12):
yield acc_11_pos, acc_12_pos
ani = FuncAnimation(fig, ani, frames=frames, interval=300)
plt.show()
However, the dot stops at each point then continue, but I want the dot moving smoothly in this speed without changing the interval. Can anyone please help?
"Smooth" would always require "more frames" in my opinion. So I do not see a way to make the movement smoother, i.e. increase the number of frames, without increasing the frames per second, i.e. changing the interval.
Here's a version with frames increased tenfold and interval reduced tenfold:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
Acc_11 = np.linspace(0,8,90) # increased frames
Acc_12 = np.ones(len(Acc_11))*4
fig = plt.figure()
axes = fig.add_subplot(111, autoscale_on=False)
axes.set_xlim(min(Acc_11), max(Acc_11))
axes.set_ylim(0, 8)
point, = axes.plot([Acc_11[0]],[Acc_12[0]], 'go')
def ani(coords):
point.set_data([coords[0]],[coords[1]])
return point,
def frames():
for acc_11_pos, acc_12_pos in zip(Acc_11, Acc_12):
yield acc_11_pos, acc_12_pos
ani = FuncAnimation(fig, ani, frames=frames, interval=30) # decreased interval
plt.show()
I am trying to animate the numpy array C3, this is an array with one channel of electrode data and I want to plot it in real time using matplotlib.
I have created my update function but nothing is printing out, I though the the syntax is you pass i through to loop through the plots and the FuncAnimation should do the rest.
Can someone please point me in the right direction?
Much appreciated!
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
data_skip = 50
def update_plot(i):
plt.cla()
plt.plot(C3[i:i+data_skip], t[i:i+data_skip])
plt.scatter(C3[i], t[i], marker='o', color='r')
plt.tight_layout()
plt.show()
ani = FuncAnimation(plt.gcf(), update_plot, interval=1000)
plt.tight_layout()
plt.show()
Remove plt.cla(), it will clear current axes. Every time you plot something on figure, plt.cla() then clears it.
You could confirm it by the following minimul example. It plots nothing
import matplotlib.pyplot as plt
import numpy as np
C3 = np.linspace(0.5, 10, 100)
t = np.linspace(0.5, 10, 100)
plt.plot(C3, t)
plt.cla()
plt.show()
Matplotlib documentation have an example to write animation code: simple_anim.py. You'd better explicitly declare fig and ax.
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
import numpy as np
C3 = np.linspace(0.5, 10, 100)
t = np.linspace(0.5, 10, 100)
data_skip = 2
fig, ax = plt.subplots()
def update_plot(i):
ax.plot(C3[i:i+data_skip], t[i:i+data_skip])
ax.scatter(C3[i], t[i], marker='o', color='r')
ani = FuncAnimation(fig, update_plot, interval=1000)
plt.tight_layout()
plt.show()
Good day !
Problem explanation:
I want to animate a Polygon which values I receive from an array (in my simple example it is a moving sqaure). I want to keep the Polygon's x-and y-values mutable. Dont worry about what movement the Polygon does. It is just an example. Working with "set_xy()" like in the solution from 'animation to translate polygon using matplotlib' is wanted.
Goal -> in every animation frame I want to load the Polygon values from the arrays (P1x,P1y,P2x,P2y,...) and update the figure.
Question:
In my code I still have problems to work with the patches. I'm trying to update the Polygon values with the index i. How do I have to define the patch? Does this have to be done bevor the animation call?
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
import matplotlib.patches as patches
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(-10,10)
ax.set_ylim(-10,10)
P1x=[0.0,0.5,1.0,1.5,2.0,2.5,3.0]
P1y=[0.0,0.0,0.0,0.0,0.0,0.0,0.0]
P2x=[1.0,1.5,2.0,2.5,3.0,3.5,4.0]
P2y=[0.0,0.0,0.0,0.0,0.0,0.0,0.0]
P3x=[1.0,1.5,2.0,2.5,3.0,3.5,4.0]
P3y=[1.0,1.0,1.0,1.0,1.0,1.0,1.0]
P4x=[0.0,0.5,1.0,1.5,2.0,2.5,3.0]
P4y=[1.0,1.0,1.0,1.0,1.0,1.0,1.0]
def init():
return patch,
def animate(i):
v = np.array([
[P1x[i], P1y[i]],
[P2x[i], P2y[i]],
[P3x[i], P3y[i]],
[P4x[i], P4y[i]]
])
patch=patches.Polygon(v,closed=True, fc='r', ec='r')
return patch,
ani = animation.FuncAnimation(fig, animate, np.arange(1, 5), init_func=init,
interval=1000, blit=True)
plt.show()
Thanks a lot for your help!
Yes, you will need to create the Polygon first and add it to the axes. Inside the animating function you may use the patch's patch.set_xy() method to update the vertices of the polygon.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
import matplotlib.patches as patches
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(-10,10)
ax.set_ylim(-10,10)
P1x=[0.0,0.5,1.0,1.5,2.0,2.5,3.0]
P1y=[0.0,0.0,0.0,0.0,0.0,0.0,0.0]
P2x=[1.0,1.5,2.0,2.5,3.0,3.5,4.0]
P2y=[0.0,0.0,0.0,0.0,0.0,0.0,0.0]
P3x=[1.0,1.5,2.0,2.5,3.0,3.5,4.0]
P3y=[1.0,1.0,1.0,1.0,1.0,1.0,1.0]
P4x=[0.0,0.5,1.0,1.5,2.0,2.5,3.0]
P4y=[1.0,1.0,1.0,1.0,1.0,1.0,1.0]
P = np.concatenate((np.array([P1x, P2x, P3x, P4x]).reshape(4,1,len(P1x)),
np.array([P1y, P2y, P3y, P4y]).reshape(4,1,len(P1x))), axis=1)
patch = patches.Polygon(P[:,:,0],closed=True, fc='r', ec='r')
ax.add_patch(patch)
def init():
return patch,
def animate(i):
patch.set_xy(P[:,:,i])
return patch,
ani = animation.FuncAnimation(fig, animate, np.arange(P.shape[2]), init_func=init,
interval=1000, blit=True)
plt.show()
I am a student and I am new to matplotlib animation.
I am trying to figure out how to animate zooming in towards the center of my 3d scatterplot, and I've included my code below. I am trying to get the zeroes to be at the middle of each axis so I am able to see the overall plot as a zoom in. I don't get an error whenever I run my code but when I run the animation the intervals change abruptly and don't seem to go in a certain pattern. Another thing I've noticed is that the zeroes are only sometimes in the middle of the axis, while the plot "glitches out".
Thank You.
import matplotlib.pylab as plt
import matplotlib.animation as animation
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
%matplotlib notebook
x = np.random.rand(100)*100
y = np.random.rand(100)*100
z = np.random.rand(100)*100
#setup figure
fig = plt.figure()
ax = fig.add_subplot(111, facecolor='LightCyan', projection = '3d')
#set up viewing window (in this case the 25 most recent values)
ax.set_xlim([-1, 1])
ax.set_ylim([-1,1])
ax.set_zlim([-1,1])
#sets up list of images for animation
plot = ax.scatter(x, y, z, color='b', marker= '*',)
def func(i):
x_lim = ax.set_xlim(-i,i)
y_lim = ax.set_ylim(-i, i)
z_lim = ax.set_zlim(-i, i)
return plot
ani = animation.FuncAnimation(fig, func, frames=100, interval=1000, blit=True)
I am making a matplotlib animation in which a quiver arrow moves across the page. This cannot be achieved in the usual way (creating one Quiver object and updating it with each frame of the animation) because although there is a set_UVC method for updating the u, v components, there is no equivalent method for changing the x, y position of the arrows. Therefore, I am creating a new Quiver object for each frame.
This works fine when I do a plt.show() and the animation is drawn on the screen. The arrow moves from left to right across the page, and when one arrow appears the previous one disappears, which is what I want. However, when I save as a gif or mp4 the previous arrows are not cleared, so I end up with a whole line of arrows appearing. How can I fix this?
My code is as follows:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation
n = 21
x = np.linspace(-1.0, 1.0, num=n)
def animate(i):
q = plt.quiver(x[i:i+1], [0], [1], [0])
return q,
plt.gca().set_xlim([-1, 1])
anim = matplotlib.animation.FuncAnimation(plt.gcf(), animate, frames=n,
repeat=True, blit=True)
plt.show()
#anim.save('anim.gif', dpi=80, writer='imagemagick')
#anim.save('anim.mp4', dpi=80, writer='ffmpeg')
The solution is found here, as suggested by Jean-Sébastien above. My code now reads:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation
n = 21
x = np.linspace(-1.0, 1.0, num=n)
q = plt.quiver(x[:1], [0], [1], [0])
def animate(i):
q.set_offsets([[x[i], 0]])
return q,
plt.gca().set_xlim([-1, 1])
anim = matplotlib.animation.FuncAnimation(plt.gcf(), animate, frames=n,
repeat=True, blit=True)
plt.show()
#anim.save('anim.gif', dpi=80, writer='imagemagick')
#anim.save('anim.mp4', dpi=80, writer='ffmpeg')
Try to clear the frame every time in your animate function. The code below worked well to me.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation
n = 21
x = np.linspace(-1.0, 1.0, num=n)
fig = plt.figure()
def animate(i):
fig.clear() # clear fig
q = plt.quiver(x[i:i+1], [0], [1], [0])
plt.gca().set_xlim([-1, 1])
return q,
anim = matplotlib.animation.FuncAnimation(plt.gcf(), animate, frames=n,
repeat=True, blit=True)
# plt.show()
# anim.save('anim.gif', dpi=80, writer='imagemagick')
anim.save('anim.mp4', dpi=80, writer='ffmpeg')