Matplotlib
In this practical you'll see a few extra functions of matplotlib, get it animated, and then have the opportunity to enhance your model.
Animate your model
Firstly, here's some code that animates a simple version of the model: animatedmodel.py. Can you get something similar working for your code?
You may find it works best in Spyder, but you may have to tell it to produce a popup window. You may have noticed that if you run your code outside of Spyder's iPython console, the graphs pop open in their own window. You can make the iPython console (and Jupyter) do this by entering the following into the console (not your program):
%matplotlib qt
To move inline again, enter:
%matplotlib inline
If you find it doesn't work for you, you may have to adjust the matplotlib "backend" – how it renders the data. This may be especially true for Macs. You can find more information on backends in the matplotlib FAQ, but for Mac users, try this (the code should be before any other matplotlib imports):
import matplotlib
matplotlib.use('macosx')
Note that if you are running this in Spyder, you may also need to tell that specifically to use a different backend (if it isn't set to pick up the changes above, but instead to use something else). Make sure you're using an IPython prompt (prompt looks like "[1]") rather than a standard Python prompt (prompt looks like ">>>"), then go to the Tools menu, the Preferences menuitem, and pick IPython console from the list on the left, the Graphics tab; and adjust the Backend drop down list to Automatic, then save your files and restart Spyder.
In general, ABM either run until some stopping condition (e.g. all the food is eaten; the model has reached a steady state (in our model this might happen if we set the grass to grow back)), or after a number of iterations. To get the above version working with your code, you'll need to ignore the number of iterations for the moment. Get the animation working in an infinite loop, and then look at the below which builds on it.
So, to get the number of iterations working isn't so bad. You just adjust the animation call to:
animation = matplotlib.animation.FuncAnimation(fig, update, interval=1, repeat=False,
frames=num_of_iterations)
To get a stopping condition working is more complicated. Essentially the frames
argument
can be either a number, an iterable, or a generator function. If it is an iterable or a generator
function it doesn't much matter what is returned from it, as long as something is (it's set up
to allow you to send data into your update function but you don't have to). So, in order to have a stopping condition,
we need a generator function that stops supplying stuff when the condition is met (for example, all
the grass is eaten). Below is the animated example above, with a stopping condition and a
limited number of iterations. I know, fancy, right? Here the stopping condition is just random. Can you get it working for
your code and stopping for a more reasonable condition (e.g. all the sheep have at least some amount in
their stomachs)?
Here's the code: animatedmodel2.py.
Other matplotlib functions
The matplotlib FAQ is a great starting point for undertstanding matplotlib.
There are a few other elements of matplotlib that you might like to know about, although we're not expecting you to implement them now.
You might be interested to know that you can save image files of the graphs, and combine them together to form movies; see also this example. The movie making requires extra software such as MEncoder or FFmpeg (not installed in our labs).
Although the matplotlib documentation can be a bit hit and miss, they do have an excellent set of examples, including how to build "shakey" graphs like xkcd.
So, that's it! We've got our working model. Clean up and comment your code. You can now use this as the basis of your own models. Go onto the next page, where we'll look at where you can take your model next.
- This page
- Enhancing the model <-- next