我写了一个函数,绘制了一个由两个不同大小的子图组成的图:
def draw_plot(data, function, sigma_value):
gs = gridspec.GridSpec(1, 5)
ax1 = subplot(gs[0, 0:3])
ax2 = subplot(gs[0, 3:5], sharey=ax1)
gs.update(wspace=0.05)
...
我应该提到这是一个模块级函数,因此在该模块的顶部我进行了导入
from pylab import *
import matplotlib.gridspec as gridspec
当我运行myplot.draw_plot(...)
时,我得到RuntimeError
。事情是这种行为是不一致的。我可以调用函数,比方说,三次,前两次我得到错误,而第三次运行OK。
Traceback是
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "myplot.py", line 105, in draw_plot
ax1 = subplot(gs[0, 0:3])
File "C:\Python32\lib\site-packages\matplotlib\pyplot.py", line 766, in subplot
a = fig.add_subplot(*args, **kwargs)
File "C:\Python32\lib\site-packages\matplotlib\figure.py", line 779, in add_subplot
a = subplot_class_factory(projection_class)(self, *args, **kwargs)
File "C:\Python32\lib\site-packages\matplotlib\axes.py", line 8380, in __init__
self._axes_class.__init__(self, fig, self.figbox, **kwargs)
File "C:\Python32\lib\site-packages\matplotlib\axes.py", line 467, in __init__
self.cla()
File "C:\Python32\lib\site-packages\matplotlib\axes.py", line 910, in cla
self._shared_y_axes.clean()
File "C:\Python32\lib\site-packages\matplotlib\cbook.py", line 1493, in clean
for key, val in mapping.items():
RuntimeError: dictionary changed size during iteration
感谢您的帮助!
修改
显然,我一直在努力弄清楚自己发生了什么,所以在Traceback
之后,我检查了clean()
中的cbook.py
功能。
def clean(self):
"""
Clean dead weak references from the dictionary
"""
mapping = self._mapping
for key, val in mapping.items():
if key() is None:
del mapping[key]
val.remove(key)
在函数中我添加了一行打印mapping.items()
,我注意到当这些项目中存在与<weakref at 0480EBA0; dead>
类似的条目时会发生错误。我完全不熟悉弱引用,所以我再次陷入困境。
编辑2
这肯定不是一个好的解决方案,但是在clean()
函数体注释出来有助于我的情况,而不会产生任何新的错误。
答案 0 :(得分:3)
我刚刚发现了一篇非常近期的帖子Safely iterating over WeakKeyDictionary and WeakValueDictionary,它有助于解决类似的问题。
因此,使用Bakuriu给出的答案,我编辑了close()
函数如下
def clean(self):
"""
Clean dead weak references from the dictionary
"""
mapping = self._mapping
for key, val in list(mapping.items()): # iterate over list now
if key() is None:
del mapping[key]
val.remove(key)
它似乎工作正常!
修改强>
我刚刚发现在matplotlib
的新版本中,该函数看起来像这样:
def clean(self):
"""
Clean dead weak references from the dictionary
"""
mapping = self._mapping
to_drop = [key for key in mapping if key() is None]
for key in to_drop:
val = mapping.pop(key)
val.remove(key)
来源:
https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/cbook.py
答案 1 :(得分:1)
只是对正在发生的事情的简短解释:
你循环遍历一个可迭代的(list,dict,等等):
for somevalue in someiterable:
#do something
在循环内部,您尝试在结构上修改iterable,这意味着您添加或删除了值。这是不允许的,因为它会混乱for循环。对此的解决方案通常是遍历可迭代的副本,让您可以自由地更改原始文件。