I wrote a function that plots a figure consisting of two subplots of different sizes:
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)
...
I should mention that this is a module-level function, so at the top of that module I make imports
from pylab import *
import matplotlib.gridspec as gridspec
When I run myplot.draw_plot(...)
, I get RuntimeError
. The thing is this behaviour is inconsistent. I can call the function, say, three times, and the first two times I get the error, whereas the third time it runs OK.
The Traceback is
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
Thanks for any help!
EDIT
Obviously I've been trying to figure out myself what is going on, so following the Traceback
I checked the clean()
function in 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)
In the function I added a line that would print mapping.items()
and I noticed that the error occurs when there are entries similar to <weakref at 0480EBA0; dead>
among those items. I'm totally unfamiliar with weak references so I'm stuck again.
EDIT 2
It's certainly not a good solution but commenting out the clean()
function body helps in my case without producing any new errors.
I've just found a very recent post Safely iterating over WeakKeyDictionary and WeakValueDictionary that helps with a very similar issue.
So using answer given by Bakuriu I edited close()
function as following
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)
and it seems to be working just fine!
EDIT
I've just found out that in a new version of matplotlib
the function looks like this:
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)
Source:
https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/cbook.py