Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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'

like image 952
Jordan Carroll Avatar asked Oct 06 '22 03:10

Jordan Carroll


2 Answers

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.

like image 78
tacaswell Avatar answered Oct 09 '22 23:10

tacaswell


The line:

 self.graph, = self.ax.hexbin(self.xData, self.yData)

(if that is where your stack trace is throwing it's exception) would be because of the comma, implying that self.ax.hexbin is an iterable object. Changing to

 self.graph = self.ax.hexbin(self.xData, self.yData)

might stop the TypeError exception. Next time, provide a few more lines in the stack trace - it might help to clarify things.

like image 21
danodonovan Avatar answered Oct 09 '22 23:10

danodonovan