防止 matplotlib 在添加数据时重绘

问题描述 投票:0回答:1

我试图绘制一些点(通过geopandas),发现添加它们会变得越来越慢,直到每个点只需要几百秒甚至更长的时间。这很难用,而且绝对不正常。

我的猜测是,每次将新数据添加到图中时,matplotlib 都会重新绘制所有内容,这由 cProfile 支持:

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   143915  479.433    0.003  479.602    0.003 collections.py:352(draw)
   137549    0.238    0.000  478.297    0.003 collections.py:1014(draw)
...
事实证明,寻找解决这个问题的方法很困难。我不知道为什么图书馆会在没有显示任何内容的情况下重绘每次更改。有一些建议使用静态后端并切换到非交互模式。然而,使用相应的配置对性能没有任何影响,因为该库默认使用静态后端和非交互模式。 单步查看源代码,我发现根本没有考虑交互模式,或者可以有条件地拦截对draw()的调用。

有没有办法让 matplotlib 推迟绘图,直到所有数据都添加到图中并准备好显示为止?

这是重现该问题的脚本。让我们看看它是否有什么不同。

from pandas import DataFrame from geopandas import GeoDataFrame, points_from_xy from matplotlib import pyplot def plot_point(figure, geodata): geodata.plot(ax=figure.gca()) figure = pyplot.figure() data = DataFrame({}) lat = 0 lon = 1 geodata = GeoDataFrame(data, geometry=points_from_xy([lon], [lat])) for i in range(300): print(i) plot_point(figure, geodata)
    
python matplotlib geopandas
1个回答
0
投票
答案是“不是开箱即用的”。库中没有禁用重绘的设置。

某些后端可能会产生批量重画的副作用。 Agg 和大多数其他人使用的基本实现会尽可能重绘。

注释从未声称提供任何保护,而是将其作为继承类的选项。

因此可以使用更保守的重绘策略

实现自定义后端并使用它。就我而言,以下内容就足够了:

from matplotlib.backend_bases import _Backend from matplotlib.backends.backend_agg import FigureCanvasAgg, _BackendAgg class FigureCanvasAggLazy(FigureCanvasAgg): def draw_idle(self, *args, **kwargs): pass # No intermediate draws needed if you are only saving to a file @_Backend.export class _BackendAggLazy(_BackendAgg): FigureCanvas = FigureCanvasAggLazy
    
© www.soinside.com 2019 - 2024. All rights reserved.