1

I have a 2D numpy array (named enviro_grid) with zeros, ones, and twos that shuffle around per loop iteration. I would like to animate the iterations of a changing colormap so that I can sort of visually verify/demonstrate that all the agents are following the behaviour I expect.

Skeleton outline of code:

import numpy as np
import random
import pylab as plt

#...initialize values, setup, seed grid with 0's, 1's, 2's, etc...

for t_weeks in range(time_limit):

    for j in range(player_n):

    #...Here lie a bunch of for/if loops which shuffle values around via rules...
    #...culminating in grid/array updates via the following line...
    #...which is seen a few times per iteration as the P[:,j]'s change.
    #...Note that P[6, j] and P[7, j] are just x, y array locations for each agent...
    #...while P[0, j] is just a designation of 1 or 2

        enviro_grid[int( P[6, j] ), int( P[7, j] )] = int( P[0, j] )

    #...Then I have this, which I don't really understand so much as...
    #... just copy/pasted from somewhere

    im = plt.imshow(enviro_grid, cmap = 'hot')
    plt.colorbar(im, orientation='horizontal')
    plt.show()

I've looked at a few links already for help; for instance, these

How to animate the colorbar in matplotlib

Colormap issue using animation in matplotlib

http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/

but I'm just too out of my league re: Python to understand half of what I'm seeing, much less tailor it to my own code. Just to help illustrate the kind of very basic help that I will probably need to be useful, the plotting I've done in the past is more of the form plot(x, y, options), and any animation I've done was just a natural byproduct of plotting during loop iterations. All of this fig.method and plt.method stuff, culminating in a final plt.show(), confuses and enrages me. The use of def() functions in all of the above examples further exacerbates my lack of clarity as far as transitioning lines to my own context.

Would anyone mind providing a working solution for this based on my code? I can provide more details if needed but am trying to keep this short per stackoverflow preference.

Thanks in advance for any help anyone can provide.

Community
  • 1
  • 1
Swerve
  • 33
  • 4

1 Answers1

1

The biggest challenge in doing simple animations in matplotlib is to understand and work around the blocking behavior of the plt.show command. It is nicely described in this question. For your specific problem, maybe something like this will be a good starting point:

import numpy as np
import pylab as plt

def get_data(): return np.random.randint(0,3,size=(5,5))

im = None
for _ in xrange(20):    # draw 20 frames
    if not im:
        # for the first frame generate the plot...
        im = plt.imshow(get_data(), cmap = 'hot', interpolation='none',vmin=0,vmax=2)    
        plt.colorbar(im, orientation='horizontal')
    else:
        # ... for subsequent times only update the data
        im.set_data(get_data())
    plt.draw()
    plt.pause(0.1)

Note that you need the plt.pause command to give your GUI enough time to actually draw the plot, but you can probably make the time much shorter.

Community
  • 1
  • 1
user8153
  • 4,049
  • 1
  • 9
  • 18
  • (Deleted a bunch of my earlier comments as I figured things out. I also just realized I deleted me saying thanks a lot for your help, so let me say it again: thanks a lot for your help!) I realized I can just link to an image. So to clarify, I put the "if" loop stuff inside my for loop/time loop, at the end, and it's "working", but doing this: http://i.imgur.com/tFNGPDD.png Also giving this error/warning message: MatplotlibDeprecationWarning: Using default event loop until function specific to this GUI is implemented warnings.warn(str, mplDeprecation). – Swerve May 01 '17 at 09:46
  • It looks like you are creating the image and the colorbar multiple times; probably once for every frame. In the code snippet that I posted the `imshow` and `colorbar` commands are executed only for the first frame, while for all subsequent frames the data of the already existing plot is being updated. I don't know why in your case those statements are executed for every frame -- is there any chance you set the `im` variable to `None` or `0` at some point? Also, I don't get this warning so it might be dependent on the backend, but it's probably safe to ignore. – user8153 May 01 '17 at 16:31
  • Oops! Yup that was it, when I replaced your for loop with my own I accidentally put the im = none inside of it instead of before it. Fixed it and it works fine. Thanks again, it looks great! Wish I could quickly post a gif of it or something. Kinda cool to watch the little white dots chasing and eating the orange ones. Next step is optimizing my horrendously ugly and inelegant code... – Swerve May 01 '17 at 22:24