My animation is not graphing properly - python

The problem
I need the animation to go fluid, but it is ploting frame by frame. The code is running in Jupyter Notebook.
Here are the libraries
import numpy as np
from matplotlib import pyplot as plt
from scipy import signal as sp
Creating the functions to convolve
t_ini=0
t_final = 11
dt=0.1
t = np.arange(t_ini,t_final,dt)
expo = np.exp(-t)*np.piecewise(t,t>=0,[1,0])
t1 = np.arange(0,10,0.1)
s = np.sin(t1)
conv_=sp.convolve(s,expo,'full')
n_conv=np.arange(min(t1)+min(t),max(t1)+max(t)+0.1,0.1)
y = [0] * len(conv_)
t2 = [0] * len(n_conv)
Here is the plotting
i = 0
for x in n_conv:
y[i] = conv_[i]
plt.cla()
t2[i] = n_conv[i]
plt.plot(t2,y)
plt.show()
plt.pause(0.5)
i = i+1

matplotlib provides for instance ArtistAnimation that allows a seamless animation of precalculated graphs. I just added a couple of lines to your code. Only thing I changed was to use enumerate to improve your code
import numpy as np
from matplotlib import pyplot as plt
from scipy import signal as sp
import matplotlib.animation as anim
t_ini=0
t_final = 11
dt=0.1
t = np.arange(t_ini,t_final,dt)
expo = np.exp(-t)*np.piecewise(t,t>=0,[1,0])
t1 = np.arange(0,10,0.1)
s = np.sin(t1)
conv_=sp.convolve(s,expo,'full')
n_conv=np.arange(min(t1)+min(t),max(t1)+max(t)+0.1,0.1)
y = [0] * len(conv_)
t2 = [0] * len(n_conv)
#prepare figure for display
fig = plt.figure()
ax = plt.axes()
#create list to collect graphs for animation
img = []
for i, x in enumerate(n_conv):
y[i] = conv_[i]
t2[i] = n_conv[i]
#append new graphs to list
newpic, = ax.plot(t2, y, c= "blue")
img.append([newpic])
#animate the list of precalculated graphs
ani = anim.ArtistAnimation(fig, img, interval = 50)
plt.show()
Output:

Related

Animating Donuts in Matplotlib

I am doing a small animation for a teaching course in which I need to draw a donut that moves around following a trajectory. However, I am having a problem with funcAnimation insofar as I don't manage to use blit to refresh the position. Here is my code with an example dataset
import numpy as np
x1 = np.random.randint(1,101,10)
y1 = np.random.randint(1,101,10)
The animation itself is done by
%matplotlib inline
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML
fig, ax = plt.subplots()
def make_circle(r,x_c,y_c):
t = np.arange(0, np.pi * 2.0, 0.01)
t = t.reshape((len(t), 1))
x = r * np.cos(t) + x_c
y = r * np.sin(t) + y_c
return np.hstack((x, y))
def draw_donut(r_o,r_i,x_c,y_c):
Path = mpath.Path
inside_vertices = make_circle(r_i,x_c,y_c)
outside_vertices = make_circle(r_o,x_c,y_c)
codes = np.ones(len(inside_vertices), dtype=mpath.Path.code_type) * mpath.Path.LINETO
codes[0] = mpath.Path.MOVETO
vertices = np.concatenate((outside_vertices[::1],inside_vertices[::-1]))
all_codes = np.concatenate((codes, codes))
path = mpath.Path(vertices, all_codes)
patch = mpatches.PathPatch(path, facecolor='#885500', edgecolor='black')
return patch
def animate(i):
return ax.add_patch(draw_donut(10,5,x1[i],y1[i]))
anim = animation.FuncAnimation(fig, animate, frames = 10, interval=100, blit = False)
ax.set_xlim(-100, 100)
ax.set_ylim(-100, 100)
ax.set_aspect(1.0)
HTML(anim.to_jshtml())
If I set blit = True I get the error
TypeError: 'PathPatch' object is not iterable
blit = False just keep plotting more donuts. Any idea how to solve this?

Matplotlib 3d scatter _facecolors3d not working

I am trying to save a 3d scatter plot animation where points appear one at a time. I made the animation work, but when I set the face colors of the points they do not take effect and all points appear blue. When I use the same color array but on static image, colors work well.
Animation Code:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation
import random
import seaborn as sns
import pandas as pd
import json
import os
from matplotlib.animation import FuncAnimation
import mpl_toolkits.mplot3d.axes3d as p3
from matplotlib import rc
from IPython.display import HTML
from itertools import product
x=[]
y=[]
for i in range(-80, 80, 10):
x.append(i)
y.append(i)
combs = list(product(x,y))
def obj(x, y):
global HISTORY
e = 2.718
res = 7*x*y/(e**(0.001*x**2 + 0.001*y**2))
return res
z = [obj(x,y) for x, y in combs]
x = [obj[0] for obj in combs]
y = [obj[1] for obj in combs]
data = [[x[i],y[i],z[i]] for i in range(len(x))]
cmap = sns.cubehelix_palette(as_cmap=True)
m = max(z) # Get the worst score so we can use it as the darkest area of the plot.
face_colors = np.array([cmap(i/m) for i in z]) # Map all of the values with cmap colors.
df = pd.DataFrame(data, columns=["x","y","z"])
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
sc = ax.scatter([],[],[], alpha=0.5)
def update(i):
sc._offsets3d = (df.x.values[:i], df.y.values[:i], df.z.values[:i])
sc._facecolors3d = face_colors[:i]
sc._facecolors2d=sc._facecolors3d
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_xlim(min(x),max(x))
ax.set_ylim(min(y),max(y))
ax.set_zlim(min(z),max(z))
ani = matplotlib.animation.FuncAnimation(fig, update, frames=len(df), interval=70)
HTML(ani.to_html5_video())
When I do not use the animation and just call plt.scatter like this:
sc = ax.scatter(df.x.values,df.y.values,df.z.values, facecolors=face_colors)
My image works well:
How can I keep these colors in my animation as well?
Code for static image:
x=[]
y=[]
for i in range(-80, 80, 10):
x.append(i)
y.append(i)
combs = list(product(x,y))
def obj(x, y):
global HISTORY
e = 2.718
res = 7*x*y/(e**(0.001*x**2 + 0.001*y**2))
return res
z = [obj(x,y) for x, y in combs]
x = [obj[0] for obj in combs]
y = [obj[1] for obj in combs]
data = [[x[i],y[i],z[i]] for i in range(len(x))]
cmap = sns.cubehelix_palette(as_cmap=True)
m = max(z) # Get the worst score so we can use it as the darkest area of the plot.
face_colors = [cmap(i/m) for i in z] # Map all of the values with cmap colors.
df = pd.DataFrame(data, columns=["x","y","z"])
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
sc = ax.scatter(df.x.values,df.y.values,df.z.values, facecolors=face_colors)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_xlim(min(x),max(x))
ax.set_ylim(min(y),max(y))
ax.set_zlim(min(z),max(z))
plt.show()
Might just be a typo. _facecolor3d instead of _facecolors3d try this:
def update(i):
sc._offsets3d = (df.x.values[:i], df.y.values[:i], df.z.values[:i])
sc._facecolor3d = face_colors[:i]
sc._edgecolor3d = face_colors[:i]

Problem with FuncAnimation to make a Matplotlib Pendulum Animation

The problem I am simulating is a simple pendulum. While I have done it before using PyGame I now decided to use matplotlib's animation tools. It is working but not with the desired effect. Simulating it in real time seems to be working. I have tweeked the interval and amount of frames but the fps is way too low. How do you increase the fps while still playing it in real time. I would greatly appreciate it. Anyway here is my code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
g = 9.80665
L = 2
mu = 0.1
t = 100
theta_0 = np.pi/3
d_theta_0 = 0
def get_d2_theta(theta,d_theta):
return -mu*d_theta-(g/L)*np.sin(theta)
def theta(t):
theta = theta_0
d_theta = d_theta_0
delta_t = 1./60
for time in np.arange(0,t,delta_t):
d2_theta = get_d2_theta(theta,d_theta)
theta += d_theta*delta_t
d_theta += d2_theta*delta_t
return theta
x_data = [0,0]
y_data = [0,0]
fig, ax = plt.subplots()
ax.set_xlim(-2, 2)
ax.set_ylim(-2.5,1)
line, = ax.plot(0, 0)
def animation_frame(i):
x = L*np.sin(theta(i))
y = -L*np.cos(theta(i))
x_data[1] = x
y_data[1] = y
line.set_xdata(x_data)
line.set_ydata(y_data)
return line,
animation = FuncAnimation(fig, func=animation_frame, frames=np.arange(0, 60, (1./60)),interval = 10)
plt.show()

3D scatter plot colorbar matplotlib Python

I cannot add a colorbar to my 3D scatter plot that is coloured in range of min and max according to the value of bifurWidth. I've tried various attempts shown on stackoverflow, none have had any success. Any help would really be appreciated, as I am at a major loss with this.
My most recent attempt is hashed out of the code shown below.
My code:
from glob import glob
from pylab import *
import numpy as np
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
def myScatter(x0,y0,power_array,c,lw,s,vmin,vmax,cmap,label,ax):
ax.scatter(x0,y0,power_array,c=c,lw=lw,s=s,vmin=min,vmax=max,cmap=cmhot,label=label)
fig = figure()
ax = fig.add_subplot(111, projection='3d')
cmhot = get_cmap("jet")
fig.tight_layout()
fig.set_size_inches(25,15)
min = 3 #colorbar range
max = 10
lw = 0 #linewidth
s = 10 #scatter size
for idx, p in enumerate(dataSorted[:,1]):
powerLoop = dataSorted[idx,0]
powerLoop = powerLoop.astype(np.float)
bifurWidthLoop = dataSorted[idx,2]
bifurWidthLoop = bifurWidthLoop.astype(np.float)
y0 = genfromtxt(p, unpack=True, usecols=[0], skiprows=19, skip_footer=1)
length = len(x0)
power_array = [powerLoop] * length
bifurWidth_array = [bifurWidthLoop] * length
label = str(bifurWidth)
a = myScatter(x0,power_array,y0,bifurWidth_array,lw,s,min,max,cmhot,label,ax)
#cax = ax.imshow(y0, interpolation='nearest', vmin=min, vmax=max)
#fig.colorbar(cax)
fig.savefig('test.png',dpi=300)
Example of an attempt and its error:
If I use fig.colorbar(a) inside or outside of the plotting for loop, I return NoneType oject has no attribute autoscale_None.
Your code doesn't run (x0,dataSorted,y0,etc missing) so can't get it to work (also note x0,power_array,y0 are wrong order in fn call). You need to return the handle to the scatter plot in order to plot a colorbar. If you change your myScatter function to return the handle,
def myScatter(x0,y0,power_array,c,lw,s,vmin,vmax,cmap,label,ax):
return ax.scatter(x0,y0,power_array,c=c,lw=lw,s=s,vmin=min,vmax=max,cmap=cmhot,label=label)
and then call plt.colorbar(a). A minimal(ish) example would be,
from glob import glob
from pylab import *
import numpy as np
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
def myScatter(x0,y0,power_array,c,lw,s,vmin,vmax,cmap,label,ax):
return ax.scatter(x0,y0,power_array,c=c,lw=lw,s=s,vmin=min,vmax=max,cmap=cmhot,label=label)
fig = figure()
ax = fig.add_subplot(111, projection='3d')
cmhot = get_cmap("jet")
fig.tight_layout()
fig.set_size_inches(25,15)
min = 3 #colorbar range
max = 10
lw = 0 #linewidth
s = 10 #scatter size
label = 'test'
power_array = np.random.random((100,10))
bifurWidth_array = np.random.random((100,10))*(max-min)+min
x0 = np.random.random((100,10))
y0 = np.random.random((100,10))
a = myScatter(x0,power_array,y0,bifurWidth_array,lw,s,min,max,cmhot,label,ax)
plt.colorbar(a)
plt.show()

Python animate contour plot for function generated in for loops

I have a three-variable function myfunc that is generated inside three for loops. I want to draw a contour plot of y vs x and animate this for different times t. However, I've looked at the various matplotlib examples on the webpage, and am still unsure of how to do this.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import animation
def myfunc(x,y,t):
w = 0.5*x + y + 4*np.sin(1.8*t)
return w
xlist = np.linspace(0,10,10)
ylist = np.linspace(-1,1,10)
tlist = np.linspace(0,50,50)
plt.figure()
for t in tlist:
for x in xlist:
for y in ylist:
w = myfunc(x,y,t)
w_vec = np.array(w)
w_contour = w_vec.reshape((xlist.size, ylist.size))
w_plot = plt.contourf(ylist,xlist,w_contour)
plt.xlabel('x', fontsize=16)
plt.ylabel('y', fontsize=16)
plt.show()
Edit: I quite like the look of dynamic_image2.py in this tutorial. This seems to get things moving, but the axes are wrong:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
def f(x,y,t):
return 0.5*x + np.sin(y) + 4*np.sin(1.8*t)
x = np.linspace(0, 10, 10)
y = np.linspace(-1, 1, 10).reshape(-1, 1)
tlist = np.linspace(0,50,50)
ims = []
for t in tlist:
x += np.pi / 15.0
y += np.pi / 20.0
im = plt.imshow(f(x,y,t))
ims.append([im])
ani = animation.ArtistAnimation(fig, ims, interval=20, blit=True,
repeat_delay=1000)
plt.show()

Categories