Scatter Animation python - python

I have my data file containing x,y coordinates of a fractal. I want to get a animation of this coordinates.
I have tried this code.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
data1=np.loadtxt('data.txt')
fig = plt.figure()
ax = plt.axes()
scat = ax.scatter([], [])
def init():
scat.set_offsets([])
return scat
def animate(i):
scat.set_offsets(data1)
return scat
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=700, interval=1, blit=True)
plt.show()
Error is 'PathCollection' object is not iterable.
I don't know much, any help will be thankful.

Related

Plotting vertical lines in matplotlib.animation over a scatter plot

I am wanting to use matplotlib.annimation to sequentially plot data points and plot vertical lines as they become known.
What I have at the moment is the following:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x = np.arange(len(data))
y = data
fig = plt.figure()
plt.xlim(0, len(data))
plt.ylim(-8, 8)
graph, = plt.plot([], [], 'o')
def animate(i):
# line_indicies = func(x[:i+1])
graph.set_data(x[:i+1], y[:i+1])
# then I would like something like axvline to plot a vertical line at the indices in line indices
return graph
anim = FuncAnimation(fig, animate, frames=100, interval=200)
# anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
plt.show()
I would like to plot vertical lines outputted from a function as described in the comments in the animate function.
The lines are subject to change as more data points are processed.
I wrote the code with the understanding that I wanted to draw a vertical line along the index of the line graph. I decided on the length and color of the vertical line, and wrote the code in OOP style, because if it is not written in ax format, two graphs will be output.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
data = np.random.randint(-8,8,(100,))
x = np.arange(len(data))
y = data
fig = plt.figure()
ax = plt.axes(xlim=(0, len(data)), ylim=(-8, 8))
graph, = ax.plot([], [], 'o')
lines, = ax.plot([],[], 'r-', lw=2)
def init():
lines.set_data([],[])
return
def animate(i):
graph.set_data(x[:i+1], y[:i+1])
# ax.axvline(x=i, ymin=0.3, ymax=0.6, color='r', lw=2)
lines.set_data([i, i],[-3, 2])
return graph
anim = FuncAnimation(fig, animate, frames=100, interval=200)
# anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
plt.show()

How do i make y-axis to be in an ascending order in matplotlib.animation? Sentdex tutorial

import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure(1)
ax1 = fig.add_subplot(1,1,1)
def animate(i):
graph_data = open('example.txt','r').read()
lines = graph_data.split('\n')
xs = []
ys = []
for line in lines:
if len(line) > 1:
x, y = line.split(',')
xs.append(x)
ys.append(y)
ax1.clear()
ax1.plot(xs, ys)
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()
Is there another way to write the code such that y-axis is in ascending order?
If so. where should I find it? This is from sentdex matplotlib tutorial
The better solution is to not do all the stuff manually and rely on numpy reading the data. Also, not clearing the axes in each loopstep may be beneficial.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
line, = ax.plot([],[])
def animate(i):
x,y = np.loadtxt("data/example.txt", unpack=True, delimiter=",")
line.set_data(x,y)
ax.relim()
ax.autoscale_view()
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()

Why does the output of animation.FuncAnimation have to be bound to a name? [duplicate]

I am trying to do an animation using the FuncAnimation module, but my code only produces one frame and then stops. It seems like it doesn't realize what it needs to update. Can you help me what went wrong?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(0,2*np.pi,100)
def animate(i):
PLOT.set_data(x[i], np.sin(x[i]))
print("test")
return PLOT,
fig = plt.figure()
sub = fig.add_subplot(111, xlim=(x[0], x[-1]), ylim=(-1, 1))
PLOT, = sub.plot([],[])
animation.FuncAnimation(fig, animate, frames=len(x), interval=10, blit=True)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(0,2*np.pi,100)
fig = plt.figure()
sub = fig.add_subplot(111, xlim=(x[0], x[-1]), ylim=(-1, 1))
PLOT, = sub.plot([],[])
def animate(i):
PLOT.set_data(x[:i], np.sin(x[:i]))
# print("test")
return PLOT,
ani = animation.FuncAnimation(fig, animate, frames=len(x), interval=10, blit=True)
plt.show()
You need to keep a reference to the animation object around, otherwise it gets garbage collected and it's timer goes away.
There is an open issue to attach a hard-ref to the animation to the underlying Figure object.
As written, your code well only plot a single point which won't be visible, I changed it a bit to draw up to current index

How to embed matplotlib funcAnimation object within PyQT GUI [duplicate]

I am trying to do an animation using the FuncAnimation module, but my code only produces one frame and then stops. It seems like it doesn't realize what it needs to update. Can you help me what went wrong?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(0,2*np.pi,100)
def animate(i):
PLOT.set_data(x[i], np.sin(x[i]))
print("test")
return PLOT,
fig = plt.figure()
sub = fig.add_subplot(111, xlim=(x[0], x[-1]), ylim=(-1, 1))
PLOT, = sub.plot([],[])
animation.FuncAnimation(fig, animate, frames=len(x), interval=10, blit=True)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(0,2*np.pi,100)
fig = plt.figure()
sub = fig.add_subplot(111, xlim=(x[0], x[-1]), ylim=(-1, 1))
PLOT, = sub.plot([],[])
def animate(i):
PLOT.set_data(x[:i], np.sin(x[:i]))
# print("test")
return PLOT,
ani = animation.FuncAnimation(fig, animate, frames=len(x), interval=10, blit=True)
plt.show()
You need to keep a reference to the animation object around, otherwise it gets garbage collected and it's timer goes away.
There is an open issue to attach a hard-ref to the animation to the underlying Figure object.
As written, your code well only plot a single point which won't be visible, I changed it a bit to draw up to current index

How to animate a seaborn's heatmap or correlation matrix?

I am relatively new to python (coming from Matlab). As one project, I am trying to create an animated plot of a correlation matrix over time. To make the plots nice, I am trying seaborn. I struggled to get the animation done at all (having issues with Matplotlib backend on a mac), but a very basic animation now works using this code from the web:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
nx = 50
ny = 50
fig = plt.figure()
data = np.random.rand(nx, ny)
im = plt.imshow(data)
def init():
im.set_data(np.zeros((nx, ny)))
def animate(i):
#xi = i // ny
#yi = i % ny
data = np.random.rand(nx, ny)
im.set_data(data)
return im
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=50, repeat = False)
Now, I was trying to adapt this to seaborn, but did not succeed. It seems that seaborn works on subplots and to animate these was far harder. The best thing I got once was a kind of recursive plot, where seaborn.heatmaps were plotted on top of each other. Also, the im.set_data method was not available.
Any suggestions are highly appreciated.
I replaced plt.imshow (casting data via set_data didn't work) with seaborn.heatmap.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import animation
fig = plt.figure()
data = np.random.rand(10, 10)
sns.heatmap(data, vmax=.8, square=True)
def init():
sns.heatmap(np.zeros((10, 10)), vmax=.8, square=True, cbar=False)
def animate(i):
data = np.random.rand(10, 10)
sns.heatmap(data, vmax=.8, square=True, cbar=False)
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=20, repeat = False)
This creates the recursive plot I struggled with.
In addition to your answer above, I wanted to do this from a list of dataframes and save as a gif. So, using your code and Serenity's answer to Matplotlib animation iterating over list of pandas dataframes
fig = plt.figure()
def init():
sns.heatmap(np.zeros((10, 10)), vmax=.8, square=True, cbar=False)
def animate(i):
data = data_list[i]
sns.heatmap(data, vmax=.8, square=True, cbar=False)
data_list = []
for j in range(20):
data = np.random.rand(10, 10)
data_list.append(data)
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=20, repeat = False)
savefile = r"test3.gif"
pillowwriter = animation.PillowWriter(fps=20)
anim.save(savefile, writer=pillowwriter)
plt.show()
Thanks!!!
Here's a complete example (tested with Matplotlib 3.0.3).
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
def animate_heat_map():
fig = plt.figure()
nx = ny = 20
data = np.random.rand(nx, ny)
ax = sns.heatmap(data, vmin=0, vmax=1)
def init():
plt.clf()
ax = sns.heatmap(data, vmin=0, vmax=1)
def animate(i):
plt.clf()
data = np.random.rand(nx, ny)
ax = sns.heatmap(data, vmin=0, vmax=1)
anim = animation.FuncAnimation(fig, animate, init_func=init, interval=1000)
plt.show()
if __name__ == "__main__":
animate_heat_map()
Based on the answer of r schmaelzle I created animated seaborn heatmap with annotaion.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import animation
class Heatmap:
def __init__(self):
self.fig, self.ax = plt.subplots()
self.anim = None
def animate(self):
def init():
sns.heatmap(np.zeros((10, 10)), vmax=.8, ax=self.ax)
def animate(i):
self.ax.texts = []
sns.heatmap(np.random.rand(10, 10), annot=True, vmax=.8, cbar=False, ax=self.ax)
self.anim = animation.FuncAnimation(self.fig, animate, init_func=init, frames=20, repeat=False)
if __name__ == '__main__':
hm = Heatmap()
hm.animate()
The trick to update annotations is to make empty ax.texts = [].
I hope it will help others! :)

Categories

Resources