I wonder if there is some way to plot a waveform point to point at a certain rate through the matplotlib so that the graph appears slowly in the window. Or another method to graph appears at a certain speed in the window and not all the points simultaneously. I've been tried this but I can only plot a section of points at a time
import numpy as np
import matplotlib.pyplot as plt
import time
x = np.arange(0,5,0.001)
y = np.sin(2*np.pi*x)
ind_i = 0
ind_f = 300
while ind_f <= len(x):
xtemp = x[ind_i:ind_f]
ytemp = y[ind_i:ind_f]
plt.hold(True)
plt.plot(xtemp,ytemp)
plt.show()
time.sleep(1)
ind_i = ind_f
ind_f = ind_f + 300
You can also do this with Matplotlib's FuncAnimation function. Adapting one of the matplotlib examples:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.arange(0,5,0.001)
y = np.sin(2*np.pi*x)
def update_line(num, data, line):
line.set_data(data[..., :num])
return line,
fig = plt.figure()
data = np.vstack((x,y))
l, = plt.plot([], [], 'r-')
plt.xlim(0, 5)
plt.ylim(-1, 1)
line_ani = animation.FuncAnimation(fig, update_line, frames=1000,
fargs=(data, l), interval=20, blit=False)
plt.show()
Related
I am trying to make an animation in 3D using Matplotlib and mpl_toolkits. For starter, I am trying to make an animation of a shifting cos wave. But when I run the program, the plot is completely empty. I have just started learning matplotlib animations, so I don't have in-depth knowledge of it. Here is my code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import matplotlib.animation as animation
fig = plt.figure()
ax = Axes3D(fig)
line, = ax.plot([],[])
print(line)
X = np.linspace(0, 6*math.pi, 100)
def animate(frame):
line.set_data(X-frame, np.cos(X-frame))
return line
anim = animation.FuncAnimation(fig, animate, frames = 100, interval = 50)
plt.show()
Here is the output:
What is wrong with my code? Why am I not getting any output?
There are two issues with your code:
use set_data_3d to update the data of a Line3D object instead of set_data
initialize the Axes3D scales before starting the animation
This should work:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import matplotlib.animation as animation
fig = plt.figure()
ax = Axes3D(fig)
# initialize scales
ax.set_xlim3d(0, 6 * math.pi)
ax.set_ylim3d(-1, 1)
ax.set_zlim3d(0, 100)
X = np.linspace(0, 6 * math.pi, 100)
line, = ax.plot([], [], [])
def animate(frame):
# update Line3D data
line.set_data_3d(X, np.cos(X - frame), frame)
return line,
anim = animation.FuncAnimation(fig, animate, frames = 20, interval = 50)
plt.show()
and yield an animation like this (I have truncated the number of frames to reduce image file size).
I'm trying to create an animated map plot using smopy and matplotlib in jupyter, but when I run the code I get two figures instead of one. The first figure is shown above the map and empty. Can anyone tell me how to fix this so that only the animation is drawn?
import smopy
import matplotlib.animation as animation
n= 1000
%matplotlib notebook
def update(curr):
if curr == n-100:
a.event_source.stop()
lons = crime_df.X[curr:curr+100]
lats = crime_df.Y[curr:curr+100]
x,y = map.to_pixels(lats,lons)
ax.scatter(x, y, c='r', alpha=0.7, s=200)
plt.title(curr)
fig = plt.figure()
ax = smopy.Map((37.6624,-122.5168,37.8231,-122.3589), z=12)
ax = ax.show_mpl(figsize=(8,8))
a = animation.FuncAnimation(fig, update, interval=100)
You should not create an additional figure, if that is undersired: Leave out plt.figure().
import smopy
import matplotlib.pyplot as plt
import matplotlib.animation as animation
n= 1000
%matplotlib notebook
def update(curr):
if curr == n-100:
a.event_source.stop()
lons = crime_df.X[curr:curr+100]
lats = crime_df.Y[curr:curr+100]
x,y = map.to_pixels(lats,lons)
ax.scatter(x, y, c='r', alpha=0.7, s=200)
plt.title(curr)
m = smopy.Map((37.6624,-122.5168,37.8231,-122.3589), z=12)
ax = m.show_mpl(figsize=(8,8))
a = animation.FuncAnimation(ax.figure, update, interval=100)
Alternatively create the figure beforehands,
fig, ax = plt.subplots(figsize=(8,8))
m = smopy.Map((37.6624,-122.5168,37.8231,-122.3589), z=12)
m.show_mpl(ax = ax)
a = animation.FuncAnimation(fig, update, interval=100)
I want to make 3D animation with matplotlib, but I don't know how to. Here is my non-working code.
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import animation
from math import *
fig = plt.figure()
ax = fig.add_subplot(111) #, projection='3d'
#setting
ax.set_xlim(-5,5)
ax.set_ylim(-5,5)
#ax.set_zlim(-5,5)
ax.set_xlabel('x')
ax.set_ylabel('y')
#ax.set_zlabel('z')
ax.grid()
f1, = ax.plot([], [], "r-", lw=1) #plot1
def gen():
for phi in np.linspace(0,2*pi,100):
yield np.cos(phi), np.sin(phi), phi
def update(data):
p1, q1, psi = data
f1.set_data(p1,q1)
#f1.set_3d_properties(psi)
ani = animation.FuncAnimation(fig, update, gen, blit=False, interval=100, repeat=True)
#ani.save('matplot003.gif', writer='imagemagick')
plt.show()
I used this example http://matplotlib.org/1.4.1/examples/animation/simple_3danim.html
and modified your code:
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import animation
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
def gen(n):
phi = 0
while phi < 2*np.pi:
yield np.array([np.cos(phi), np.sin(phi), phi])
phi += 2*np.pi/n
def update(num, data, line):
line.set_data(data[:2, :num])
line.set_3d_properties(data[2, :num])
N = 100
data = np.array(list(gen(N))).T
line, = ax.plot(data[0, 0:1], data[1, 0:1], data[2, 0:1])
# Setting the axes properties
ax.set_xlim3d([-1.0, 1.0])
ax.set_xlabel('X')
ax.set_ylim3d([-1.0, 1.0])
ax.set_ylabel('Y')
ax.set_zlim3d([0.0, 10.0])
ax.set_zlabel('Z')
ani = animation.FuncAnimation(fig, update, N, fargs=(data, line), interval=10000/N, blit=False)
#ani.save('matplot003.gif', writer='imagemagick')
plt.show()
Here is the following code for a sphere moving to the right and off the screen.
You will have to run this code in a folder for tidiness, as it generates 26 .png images (and a .gif image):
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from numpy import sin, cos, pi, outer, ones, size, linspace
# Define x, y, z lists for sphere
a = linspace(0, 2 * pi)
b = linspace(0, pi)
x = 10 * outer(cos(a), sin(b))
y = 10 * outer(sin(a), sin(b))
z = 10 * outer(ones(size(a)), cos(b))
# The amount of frames in the animation
frames = 26
# Generate each frame
for n in range(frames):
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x, y, z, color=('b'))
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
ax.set_xlim(-8,8)
ax.set_xlim(-8,8)
ax.set_xlim(-8,8)
plt.savefig(f"{n}.png")
plt.close()
# Add 1 to the x so the sphere moves right by 1
x += 1
# Use pillow to save all frames as an animation in a gif file
from PIL import Image
images = [Image.open(f"{n}.png") for n in range(frames)]
images[0].save('ball.gif', save_all=True, append_images=images[1:], duration=100, loop=0)
Output:
I have written the following code with the help of online search. My intention here is to get a real time graph with time on x axis and some randomly generated value on y axis
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
import numpy as np
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
def animate(i):
xar = []
yar = []
x,y = time.time(), np.random.rand()
xar.append(x)
yar.append(y)
ax1.clear()
ax1.plot(xar,yar)
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()
With the above code I just see the range of y axis changing continuously and the graph will not appear in the figure.
The problem is that you never update xvar and yvar. You can do that by moving the definitions of the lists outside the definition of animate.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
import numpy as np
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
xar = []
yar = []
def animate(i):
x,y = time.time(), np.random.rand()
xar.append(x)
yar.append(y)
ax1.clear()
ax1.plot(xar,yar)
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()
I'm producing a series of scatterplots, where I keep most of the plot (besides the scatter plot) between each plot. This is done like so: Keeping map overlay between plots in matplotlib
Now I want to add annotation to the plot:
for j in range(len(n)):
plt.annotate(n[j], xy = (x[j],y[j]), color = "#ecf0f1", fontsize = 4)
However, this annotation stays on the plot between plots. How can I clear the annotation after each figure is saved?
You can remove an artist using remove().
ann = plt.annotate (...)
ann.remove()
After removal it may be necessary to redraw the canvas.
Here is a complete example, removing several annotations within an animation:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation
fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01)
f = lambda x: np.sin(x)
line, = ax.plot(x, f(x))
scat = plt.scatter([], [], s=20, alpha=1, color="purple", edgecolors='none')
ann_list = []
def animate(j):
for i, a in enumerate(ann_list):
a.remove()
ann_list[:] = []
n = np.random.rand(5)*6
scat.set_offsets([(r, f(r)) for r in n])
for j in range(len(n)):
ann = plt.annotate("{:.2f}".format(n[j]), xy = (n[j],f(n[j])), color = "purple", fontsize = 12)
ann_list.append(ann)
ani = matplotlib.animation.FuncAnimation(fig, animate, frames=20, interval=360)
ani.save(__file__+".gif",writer='imagemagick', fps=3)
plt.show()