7

サイズの異なる 2 つのサブプロットで構成される図をプロットする関数を作成しました。

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ます。問題は、この動作に一貫性がないことです。たとえば、関数を 3 回呼び出すことができます。最初の 2 回はエラーが発生しますが、3 回目は正常に実行されます。

トレースバックは

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>。私は弱い参照にまったく慣れていないので、また立ち往生しています。

EDIT 2 確かに良い解決策ではありませんが、関数本体をコメントアウトするとclean()、私の場合、新しいエラーを発生させることなく役立ちます。

4

2 に答える 2

3

非常によく似た問題に役立つ非常に最近の投稿、WeakKeyDictionary と WeakValueDictionaryを安全に繰り返すことを見つけました。

したがって、バクリウからの回答を使用して、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

于 2012-09-14T18:23:23.107 に答える
1

何が起こっているのかを簡単に説明します。

次のように、イテラブル (リスト、辞書など) をループしました。

for somevalue in someiterable:
    #do something

そして、ループ内で iterable を構造的に変更しようとしました。つまり、値を追加または削除しました。これは、for ループを台無しにするため、許可されていません。これに対する解決策は通常、反復可能オブジェクトのコピーを反復処理して、オリジナルを自由に変更できるようにすることです。

于 2012-09-14T18:24:40.873 に答える