如何更新Matplotlib的六边形图?

5
我有一个在GTK.Window中嵌入了matplotlib hexbin的图表,用于显示一些数据(x,y)。我希望当收到新数据(通过UDP)时,plot更新。但是我遇到了一些问题。
我可以用几种不同的方法来解决它,但都不够“高效”(也就是说-重新绘制plot需要太长时间)。我查看了这里并尝试根据建议的答案模拟我的hexbin,但无法使其正常工作。我一直收到以下错误: TypeError: 'PolyCollection' object is not iterable. 我猜测hexbins不能像标准的plots那样更新。 示例代码:
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()

代码的使用方式如下:

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

这只是我使用代码的一个非常小的例子。我对matplotlib没有太多经验,所以很可能我的做法是错误的(这也是最有可能的)。
因此,我的最终问题是 - 如何更新matplotlib hexbin图?
编辑:感谢danodonovan的答案,我修改了代码并删除了self.graph = self.ax.hexbin(...)后面的逗号。
抛出的新错误是:AttributeError: 'PolyCollection' object has no attribute 'set_xdata'

如果您能够提供堆栈跟踪中错误上面的行,那么它可能会帮助我们找出代码的哪个部分引发了该异常。 - danodonovan
3个回答

2

这行代码:

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

如果你的堆栈跟踪引发异常的地方是这个位置,那么原因可能是逗号,这意味着self.ax.hexbin是可迭代对象。可以尝试更改为

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

可能会停止TypeError异常。下次请在堆栈跟踪中提供更多行——这可能有助于澄清问题。


那个错误已经修复了,但现在我又遇到了 AttributeError: 'PolyCollection' object has no attribute 'set_xdata' 的问题。下次我会贴出更多堆栈跟踪信息!我还是 Python 的新手,对它还不是很熟悉。所以我不太确定如何轻松访问堆栈跟踪。 - Jordan Carroll
很酷 - 我认为你的新错误可能需要一个新的问题!PS:堆栈跟踪只是异常行上面的行 - 它有助于深入挖掘错误的根源。 - danodonovan
我认为这可能需要进行编辑,因为我的问题仍然没有得到解答。感谢您的帮助。 - Jordan Carroll
我知道问题,但问题仍然是“如何更新matplotlib的hexbin?”这个问题仍未得到回答。 - Jordan Carroll

2

我认为当前无法完成这个任务,hexbin 将 x,y 的列表转换为多边形的集合。 polyCollection 只是由顶点、边缘和面颜色组成的列表,我认为它没有携带任何有关如何生成它的语义信息。

最好的方法是放弃旧的 hexbin 并用新的替换它。

如果您真的想要能够进行原地更新,请使用正方形2D直方图(这样您就可以使用 imshow),或者修改 hexbin 以返回补丁的列表(而不是 polyCollection),并自行跟踪分箱情况。


当使用动画或滑块更新“Axes”时,如何“nuke”旧的hexbin? - shadowtalker

0
回答你预期的问题,不要调用set_xdata,尝试使用update_from。我不能保证这会起作用,但是我建议你试一下。
def update(self, xData, yData):
    # update your data structures
    self.xData = np.append(self.xData, xData)
    self.yData = np.append(self.yData, yData)

    # create a new hexbin - not connected to anything, with the new data
    new_hexbin = self.ax.hexbin(self.xData, self.yData)

    # update the viewed hexbin from the new one
    self.graph.update_from(new_hexbin)
    self.figure.canvas.draw()

请注意,如果没有更多的代码或解释,这只是猜测!该类的文档在这里update_from方法来自父类

这个可以运行,但是非常慢。我开始觉得可能没有一种高效的方法来解决这个问题。 - Jordan Carroll
每次调用 update_from 似乎都会添加新的十六进制,而不是替换现有的。 - shadowtalker
我最终通过首先调用 ax.clear(),然后每次完全重绘坐标轴(包括标签、网格等)来解决这个问题。 - shadowtalker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接