animate traffic using matplotlib - python

I would like to make a video with some car traffic. For this I have all state information of all cars. Drawing the situation for a given time is no problem. Animation is. I made some code that looks like the code below but this does not work: nothing is moving. I do not understand the basics of animation. Can someone point me in the right direction?
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.animation as manimation
FFMpegWriter = manimation.writers['ffmpeg']
writer = FFMpegWriter(fps=10)
def animate_traffic():
fig=plt.figure(1)
ax=fig.add_subplot(1,1,1)
tsim=tstart
with writer.saving(fig, "roadtest.mp4", 100):
for i in range(100):
draw_roadlayout()
for car in cars:
# draw each of the cars on the road
# based on time tsim
plt.grid(False)
ax.axis(plt_area)
fig = plt.gcf()
writer.grab_frame()
ax.cla()
tsim+=timestep
plt.close(1)
Thank you.
updated: after writing, I clear the area. The full version works for me now.

If you can generate images that show movement, you can just save them and create video using ffmpeg.

ax.cla() was a large part of the answer. Things can really improve but it works.

Related

Wobbling in matplotlib animation

This is my first post, so I apologise if I am doing something wrong. I couldn't find any similar questions.
I am trying to generate an animation/video using matplotlib. The animation shows a dot moving along a curve. In my attempt to do this, I can see the point wobbling as it moves along the curve. How can I get rid of this effect? Here's a short script able to reproduce the effect and a gif animation. Thanks in advance
import numpy as np
import matplotlib.pyplot as plt
N=800#The bigger this number the worse the effect
s=np.linspace(0,2*np.pi,N)
xy=np.array([s,np.power(s,0.8)])#
plt.ion()
fig, ax=plt.subplots()
line1,=ax.plot(xy[0,:],xy[1,:],'-g')
t=0
ms=8
line2,=ax.plot(xy[0,t],xy[1,t],'or',markersize=ms)
ax.set_aspect('equal')
disc=1
M=N#int(N/2)
for lab in range(0,M,disc):
line1.set_xdata(xy[0,:])
line1.set_ydata(xy[1,:])
line2.set_xdata(xy[0,lab])
line2.set_ydata(xy[1,lab])
fig.canvas.draw()
fig.canvas.flush_events()
print("done!")

How do you animate the array using Matplotlib?

I have made conways game of life but dont know how to animate the cellular automata. I want to see them moving step by step in a single window.
i feel as though its something simple, but cant quite figure out what. I'd prefer it if things were kept to matplotlib. The rule function adds/deletes values on the array in accordance with the game of life by the way.
cheers.
***import numpy
import time
import random
import matplotlib.pyplot as plt
dimension=100
a=numpy.zeros((dimension, dimension))
number_of_automata=200
iterations=1000
count=0
def main():
global its
its=0
while its!=iterations:
rule()
print_function()
def print_function():
plt.imshow(a, interpolation='none')
plt.show()
generate_random_points()
main()
```***

Suppress display of final frame in matplotlib animation in jupyter

I am working on a project that involves generating a matplotlib animation using pyplot.imshow for the frames. I am doing this in a jupyter notebook. I have managed to get it working, but there is one annoying bug (or feature?) left. After the animation is created, Jupyter shows the last frame of the animation in the output cell. I would like the output to include the animation, captured as html, but not this final frame. Here is a simple example:
import numpy as np
from matplotlib import animation
from IPython.display import HTML
grid = np.zeros((10,10),dtype=int)
fig1 = plt.figure(figsize=(8,8))
ax1 = fig1.add_subplot(1,1,1)
def animate(i):
grid[i,i]=1
ax1.imshow(grid)
return
ani = animation.FuncAnimation(fig1, animate,frames=10);
html = HTML(ani.to_jshtml())
display(html)
I can use the capture magic, but that suppresses everything. This would be OK, but my final goal is to make this public, via binder, and make it as simple as possible for students to use.
I have seen matplotlib animations on the web that don't seem to have this problems, but those used plot, rather than imshow, which might be an issue.
Any suggestions would be greatly appreciated.
Thanks,
David
That's the answer I got from the same thing I was looking for in 'jupyter lab'. Just add plt.close().
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML
grid = np.zeros((10,10),dtype=int)
fig1 = plt.figure(figsize=(8,8))
ax1 = fig1.add_subplot(1,1,1)
def animate(i):
grid[i,i]=1
ax1.imshow(grid)
return
ani = animation.FuncAnimation(fig1, animate,frames=10);
html = HTML(ani.to_jshtml())
display(html)
plt.close() # update

Matplotlib is slow when plotting many graphs on a single plot

As the title says when I try to graph a bunch of graphs, it takes a very long time. For example if I try to plot a silly example like this 10000 times:
n=10000
numbers = []
for i in range(n):
numbers.append(i)
for i in range(n):
plt.plot(numbers)
plt.show()
It will take about a minute to show the plot.
I know doing this will make it faster
import matplotlib
matplotlib.use('GTKAgg')
But is there any other way to make plotting a bunch of graphs faster? Any suggestions would be much appreciated, thanks!
You could do a dynamic plot with plt.ion()
example:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
su = fig.add_subplot(111)
su.axis([-1, 1, -1, 1])
plt.ion() # allows for dynamic plot
for i in range(1000):
y = np.random.random()
su.scatter(y**2, y)
plt.pause(0.4)
while True:
plt.pause(0.05)
This allows you to see points as they come up on your graph.
Is this what you want?
EDIT:
Maybe you could try using matplotlib.pyplot's savefig functionality
https://matplotlib.org/devdocs/api/_as_gen/matplotlib.pyplot.savefig.html
You could have your computer save all of your figures to separate png files. Then you can look at the pictures any time. This method requires minimal time on your part, just let the program run in the background for a bit while it makes the pngs, and you can view them without having to regenerate them at any time.

Animating a Quadmesh from pcolormesh with matplotlib

As a result of a full day of trial and error, I'm posting my findings as a help to anyone else who may come across this problem.
For the last couple days, I've been trying to simulate a real-time plot of some radar data from a netCDF file to work with a GUI I'm building for a school project. The first thing I tried was a simple redrawing of the data using the 'interactive mode' of matplotlib, as follows:
import matplotlib.pylab as plt
fig = plt.figure()
plt.ion() #Interactive mode on
for i in range(2,155): #Set to the number of rows in your quadmesh, start at 2 for overlap
plt.hold(True)
print i
#Please note: To use this example you must compute X, Y, and C previously.
#Here I take a slice of the data I'm plotting - if this were a real-time
#plot, you would insert the new data to be plotted here.
temp = plt.pcolormesh(X[i-2:i], Y[i-2:i], C[i-2:i])
plt.draw()
plt.pause(.001) #You must use plt.pause or the figure will freeze
plt.hold(False)
plt.ioff() #Interactive mode off
While this technically works, it also disables the zoom functions, as well as pan, and well, everything!
For a radar display plot, this was unacceptable. See my solution to this below.
So I started looking into the matplotlib animation API, hoping to find a solution. The animation did turn out to be exactly what I was looking for, although its use with a QuadMesh object in slices was not exactly documented. This is what I eventually came up with:
import matplotlib.pylab as plt
from matplotlib import animation
fig = plt.figure()
plt.hold(True)
#We need to prime the pump, so to speak and create a quadmesh for plt to work with
plt.pcolormesh(X[0:1], Y[0:1], C[0:1])
anim = animation.FuncAnimation(fig, animate, frames = range(2,155), blit = False)
plt.show()
plt.hold(False)
def animate( self, i):
plt.title('Ray: %.2f'%i)
#This is where new data is inserted into the plot.
plt.pcolormesh(X[i-2:i], Y[i-2:i], C[i-2:i])
Note that blit must be False! Otherwise it will yell at you about a QuadMesh object not being 'iterable'.
I don't have access to the radar yet, so I haven't been able to test this against live data streams, but for a static file, it has worked great thus far. While the data is being plotted, I can zoom and pan with the animation.
Good luck with your own animation/plotting ambitions!

Categories