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()
```***
Related
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!")
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.
Let's say I have a function called trajectory that plots the position of a few objects in a 2D plot.
import matplotlib.pyplot as plt
def trajectory(listOfObjects, time):
#Stuff happens here
plt.scatter(x,y)
I iterate this function so it plots new points in the same graph, effectively plotting a full trajectory over enough iterations. Something like this:
while True:
time += 1
trajectory(listOfObjects, time)
plt.pause(0.001)
Now I want this program to run embedded in a Tkinter window. How can I achieve this? I don't know how to run this loop indefinitely while also using tkinter's mainloop()
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.
So I'm representing a token ring network (doing the simulation in SimPy), I'm a totally newbie to matplotlib, but I was told that it'd be really good for representing my simulation visually.
So I googled around and found out how to draw shapes and lines - using add_patch and add_line respectively to the axes (I believe). So now I have this output which is absolutely fine:
(can't post images yet!!)
http://img137.imageshack.us/img137/7822/screenshot20100121at120.png
But I'm getting this using the pylab.show() function, and what I think I want is to achieve this using the pylab.plot() function so that I can then update it as my simulation progresses using pylab.draw() afterward.
My code is as follows:
plab.ion()
plab.axes()
for circ in self.circleList:
plab.gca().add_patch(circ)
for line in self.lineList:
plab.gca().add_line(line)
plab.axis('scaled')
plab.show()
Where circleList and lineList are lists containing the circles and lines on the diagram
I'm probably misunderstanding something simple here, but I can't actually find any examples that aren't overtly graph based that use the plot() function.
Clarification:
How can I get that same output, using pylab.plot() instead of pylab.show() ?
Replicating your image using the plot method:
from pylab import *
points = []
points.append((-0.25, -1.0))
points.append((0.7, -0.7))
points.append((1,0))
points.append((0.7,1))
points.append((-0.25,1.2))
points.append((-1,0.5))
points.append((-1,-0.5))
points.append((-0.25, -1.0))
a_line = plot(*zip(*points))[0]
a_line.set_color('g')
a_line.set_marker('o')
a_line.set_markerfacecolor('b')
a_line.set_markersize(30)
axis([-1.5,1.5,-1.5,1.5])
show()
EDIT BASED ON COMMENTS
This uses python multiprocessing library to run the matplotlib animation in a separate process. The main process uses a queue to pass data to it which then updates the plot image.
# general imports
import random, time
from multiprocessing import Process, Queue
# for matplotlib
import random
import numpy as np
import matplotlib
matplotlib.use('GTKAgg') # do this before importing pylab
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
def matplotLibAnimate(q,points):
# set up initial plot
fig = plt.figure()
ax = fig.add_subplot(111)
circles = []
for point in points:
ax.add_patch(Circle(point,0.1))
a_line, = ax.plot(*zip(*points))
a_line.set_color('g')
a_line.set_lw(2)
currentNode = None
def animate(currentNode = currentNode):
while 1:
newNode = q.get()
if currentNode: currentNode.remove()
circle = Circle(newNode,0.1)
currentNode = ax.add_patch(circle)
circle.set_fc('r')
fig.canvas.draw()
# start the animation
import gobject
gobject.idle_add(animate)
plt.show()
#initial points
points = ((-0.25, -1.0),(0.7, -0.7),(1,0),(0.7,1),(-0.25,1.2),(-1,0.5),(-1,-0.5),(-0.25, -1.0))
q = Queue()
p = Process(target = matplotLibAnimate, args=(q,points,))
p.start()
# feed animation data
while 1:
time.sleep(random.randrange(4))
q.put(random.sample(points,1)[0])
Of course, after doing this I think you'll be better served with whatnick's image solution. I'd create my own GUI and not use matplotlibs built in widget. I'd then "animate" my GUI by generating PNGs and swapping them.
It sounds like Mark has the answer you were looking for, but if you decide to go with whatnick's approach and build an animation from individual pngs, here is the code to implement Amit's suggestion to use mencoder (from http://en.wikibooks.org/wiki/Mplayer):
mencoder mf://*.png -mf w=400:h=400 -ovc lavc -lavcopts vcodec=xvid -of avi -o output.avi
The core technique is to update the data of the elements being rendered using set_data. Then call draw(). See if your circle and line elements have set_data functions. Otherwise you can use pyvtk. The other option is to render and save the plots to png files and later build an animation from those.