Jordan Carroll Jordan Carroll - 20 days ago 6
Python Question

How do I update a matplotlib hexbin plot?

I have a

matplotlib
hexbin
embedded in a
GTK.Window
that graphs some data (x,y). I want the
plot
to update when new data is received (via
UDP
). I am having some trouble though.

I can get it to work in several different ways, but none have been "efficient" (Meaning - redrawing the
plot
takes too long). I looked here and attempted to model my hexbin after the suggested answer but could not get this to work at all. I keep receiving the following error:

TypeError: 'PolyCollection' object is not iterable.


I'm guessing that
hexbins
cannot be update in the same way as standard
plots
.

Sample Code:

class graph:
def __init__(self):
self.window = gtk.Window()
self.figure = plt.figure()
self.ax = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self.figure)
self.window.add(self.canvas)

self.graph = None

def plot(self, xData, yData):
if len(xData) > 1 and len(yData) > 1:
self.graph, = self.ax.hexbin(self.xData, self.yData)
###############################################
####This is where the code throws the error####

def update(self, xData, yData):
self.graph.set_xdata(np.append(self.graph.get_xdata(), xData))
self.graph.set_ydata(np.append(self.graph.get_ydata(), yData))
self.figure.canvas.draw()


The code is used like this:

graph = graph()
graph.plot(someXData, someYData)
# when new data is received
graph.update(newXData, newYData)


This is just a very small example of how I'm using the code. I don't have much experience with
matplotlib
so there is chance I could be going about this completely wrong. (which is most likely what I am doing)

So my ultimate question is - How do you update a
matplotlib
hexbin
plot?





Edit: Thanks to danodonovan's answer, I altered my code and removed the ',' after
self.graph = self.ax.hexbin(...)


The new error thrown is:
AttributeError: 'PolyCollection' object has no attribute 'set_xdata'

Answer

I don't think that this can be done currently, hexbin converts list of x,y -> a collections of polygons. The polyCollection is just a list of verticies, edges, and face colors, I don't think it carries any semantic information about how it was generated.

The best approach is to nuke the old hexbin and replace it with a new one.

If you really want to be able to update in-place either use a square 2d histogram (so you can use imshow), or you can modify hexbin to return a list of patches (instead of a polyCollection) and keep track of the binning your self.