【问题标题】:Plotting in loop hangs matplotlib: strange memory leak?循环中的绘图挂起matplotlib:奇怪的内存泄漏?
【发布时间】:2021-07-02 14:12:54
【问题描述】:

我在字典中有一堆时间戳值,例如 pandas.DataFrame -s,如下所示:

dfS[k1] = df1
dfS[k2] = df2
...

像这样绘制到同一轴时:

dfS[k1].plot(ax=ax1)
dfS[k2].plot(ax=ax1)
...

有效,循环中相同:

for k in dfS.keys():
    dfS[k].plot(ax=ax1)

大约 20 秒后,matplotlib 崩溃并显示消息:

Traceback (most recent call last):
  File "testDataDisplay.py", line 66, in <module>
    dfS[k].plot(ax=ax)
  File "/usr/lib/python3/dist-packages/pandas/plotting/_core.py", line 847, in __call__
    return plot_backend.plot(data, kind=kind, **kwargs)
  File "/usr/lib/python3/dist-packages/pandas/plotting/_matplotlib/__init__.py", line 61, in plot
    plot_obj.generate()
  File "/usr/lib/python3/dist-packages/pandas/plotting/_matplotlib/core.py", line 269, in generate
    self._post_plot_logic_common(ax, self.data)
  File "/usr/lib/python3/dist-packages/pandas/plotting/_matplotlib/core.py", line 437, in _post_plot_logic_common
    self._apply_axis_properties(ax.xaxis, rot=self.rot, fontsize=self.fontsize)
  File "/usr/lib/python3/dist-packages/pandas/plotting/_matplotlib/core.py", line 520, in _apply_axis_properties
    labels = axis.get_majorticklabels() + axis.get_minorticklabels()
  File "/usr/lib/python3/dist-packages/matplotlib/axis.py", line 1207, in get_majorticklabels
    ticks = self.get_major_ticks()
  File "/usr/lib/python3/dist-packages/matplotlib/axis.py", line 1378, in get_major_ticks
    numticks = len(self.get_majorticklocs())
  File "/usr/lib/python3/dist-packages/matplotlib/axis.py", line 1283, in get_majorticklocs
    return self.major.locator()
  File "/usr/lib/python3/dist-packages/pandas/plotting/_matplotlib/converter.py", line 988, in __call__
    locs = self._get_default_locs(vmin, vmax)
  File "/usr/lib/python3/dist-packages/pandas/plotting/_matplotlib/converter.py", line 968, in _get_default_locs
    self.plot_obj.date_axis_info = self.finder(vmin, vmax, self.freq)
  File "/usr/lib/python3/dist-packages/pandas/plotting/_matplotlib/converter.py", line 588, in _daily_finder
    info = np.zeros(
MemoryError: Unable to allocate 45.2 GiB for an array with shape (1617786887,) and data type [('val', '<i8'), ('maj', '?'), ('min', '?'), ('fmt', 'S20')]

看起来 matplotlib 将时间戳解释为形状,因为 total number 的数据点是只是 608。以下是一些供参考:

dfS['pRp:1:avg5min'].head(4)
                 pRp:1:avg5min
2021-04-07 14:14:30        64.6226
2021-04-07 14:14:35        64.1258
2021-04-07 14:14:40        64.5340
2021-04-07 14:14:45        66.2782

for key in dfS.keys():
    print(key, end=' ')
    print(dfS[key].shape)

pRp:0:avg5min (5, 1)
pRp:0:raw (299, 1)
pRp:1:avg5min (5, 1)
pRp:1:raw (299, 1)

matplotlib.__version__
'3.3.0'

python3 --version
Python 3.8.6

pd.__version__
'1.0.5'

有什么建议吗?

【问题讨论】:

  • 请注意,您正在使用 pandas 代码,而不是 matplotlib。您能否添加完整的错误跟踪(作为文本)?您是否尝试打印dfS[k].head() 和类似的调试?你运行的是什么版本的熊猫?您尝试升级了吗?
  • @JohanC,我已经用请求的数据更新了帖子,但升级除外,因为一切都在新安装的 apt-get upgrade-ed 主机上。
  • 我真的认为尝试使用最新的 matplotlib 和 pandas 版本仍然是有意义的。像pip install matplotlib pandas --upgrade 这样的东西。也许它没有帮助,但最好总是运行最新的错误修复。这些项目的开发速度很快,每年有数千个修复和扩展。
  • @JohanC 不幸的是,通过 pip 将 matplotlib、pandas 更新到最新版本并没有解决这种奇怪的行为。

标签: python pandas matplotlib crash time-series


【解决方案1】:

这应该是一个评论而不是一个答案 - 但由于 stackoverflow 决定我只能用 50 个声誉点发表评论,我将把它作为一个答案:

您似乎正在加载多个数据帧,每个数据帧都有自己的时间序列和多个数据列,因此达到了内存限制。

当你表演时

for k in dfS.keys():
    dfS[k].plot(ax=ax1)

你绘制整个数据框。

也许这样的事情会帮助你:

for k in dfS.keys():
    dfS[k].plot(x="columnName", ax=ax1)

其中columnName 表示数据框特定列的名称。

这里真的很难猜出确切的问题,因为我们不知道输入数据的样子——也许你在这里发布数据内容的最小版本或标题版本。

【讨论】:

  • 每个都是带有 DateTime 索引的单列。我不知道如何在这里引用索引的名称,dfS[k].index 解析为时间戳列表。
猜你喜欢
  • 1970-01-01
  • 2012-07-06
  • 2015-05-09
  • 2021-03-28
  • 2020-12-19
  • 2011-04-01
  • 2012-03-07
  • 2012-06-08
相关资源
最近更新 更多