0

I wrote a python script that uses a heuristic to cluster 2D points in space. I'm representing each cluster using different cluster.

Presently, the structure of my program is:

def cluster():
   while True:
       <do_some_work>
       if <certain_condition_is_met>:
            print "ADDED a new cluster:",cluster_details
       if <breaking_condition_is_met>:
            break
   return Res

def plot_cluster(result):
    <chooses a unique color for each cluster, and calls 
    pyplot.plot(x_coods,y_coods)
    for each cluster>

def driver_function():
   result = cluster()
   plot_cluster(result)
   pyplot.show()

That is, presently, I just obtain the final image of clustered points, where each cluster is represented by a different color.

However, I need to create an animation of how the program proceeds, i.e., something like: "Initially, all points should be of same color, say blue. Then, as is cluster() function, instead of simply printing "ADDED a new cluster", the color of those points in the new cluster, should be changed in the image already present on screen.

Is there any way I can generate a video of such a program using matplotlib? I saw an example of

`matplotlib.animation.FuncAnimation( ..., animate, ...)`

but it repeatedly calls the animate function that should return plottable values, which I think my program cannot.

Is there any way to obtain such a video of how this program proceeds?

pymd
  • 4,021
  • 6
  • 26
  • 27
  • http://stackoverflow.com/questions/14347630/using-events-with-matplotlib-in-a-for-loop/14352035#14352035 use the `yield` key word – tacaswell Sep 06 '13 at 14:55
  • you can also use `ArtistAnimation` which you hand in a stack of artists. – tacaswell Sep 06 '13 at 14:55
  • to clarify my first comment, put yield statements in your program which turns it into a generator, and then pass that in as the third (?) argument to `FuncAnimation ` – tacaswell Sep 06 '13 at 15:07
  • http://stackoverflow.com/questions/8636931/matplotlib-python-help-in-explaining-an-animation-example – tacaswell Sep 06 '13 at 15:07

2 Answers2

1

To get this to work like you want will require a bit of refactoring, but I think something like this will work:

class cluster_run(object):
    def __init__(self, ...):
        # what ever set up you want
        self.Res = None

    def reset(self):
        # clears all work and starts from scratch
        pass

    def run(self):
        self.reset()
        while True:
            #<do_some_work>
            if <certain_condition_is_met>:
                print "ADDED a new cluster:",cluster_details
                yield data_to_plot
            if <breaking_condition_is_met>:
                break

            self.Res = Res


class culster_plotter(object):
    def __init__(self):
        self.fig, self.ax = plt.subplots(1, 1)

    def plot_cluster(self, data_to_plot):
        # does what ever plotting you want.
        # fold in and
        x_coords, y_coords)
        ln = self.ax.plot(x_coords, y_coords)
        return ln

cp = cluster_plotter()
cr = cluster_run()

writer = animation.writers['ffmpeg'](fps=30, bitrate=16000, codec='libx264')
ani = animation.FuncAnimation(cp.fig, cp.plot_cluster, cr.run())
ani.save('out.mp4', writer=writer)
plot_cluster(cr.Res)
tacaswell
  • 84,579
  • 22
  • 210
  • 199
0

Would it be sufficient to use pyplot.savefig('[frame].png'), where [frame] is the frame number of your plot in sequence, and then stitch these images together using a codec such as ffmpeg?

Dman2
  • 700
  • 4
  • 10