6

特定の実験用のプロット ツールのクラスを構築しています。現在、imshow() を使用する静的プロットと、 imshow() を使用する「ムービー」形式の 2 つのプロット メソッドがあります。

メソッドと将来のメソッドの両方が、私が作成する可能性のある特定のプロット メソッドと同じパラメーターを取得します。プロット クラスが使用される時点で、これらすべてのパラメーターが構成オブジェクトに含まれています。

すべてのプロット メソッドでコードを書き直したくありません。vmin、vmax、extent_dim、Xlocs、Xlabels、Ylocs、Ylabels の引数を設定するオブジェクト (私が思うに AxesImage) を初期化したいと思います。

次に、そのオブジェクトを他の特定のことを行うさまざまなメソッドに渡すだけです。これを行う方法がわかりません...

import matplotlib.pyplot as plt

data = data_dict[type] # could be real part of a complex number, phase, or the mag...
v_min, v_max = self.get_data_type_scale(data_dict, Type)
freq = data_dict['freq']

# essentially sets the aspect of the plot since the x and y resolutions could be different   
extent_dim = self._get_extent(2)
# gets the labels for physical dimensions of the experiment
Xlocs,Xlabels,Ylocs,Ylabels = self._get_ticks(5,5,extent_dim)

# in the guts of a plot method, the basic idea is the call below.  

plt.imshow(data[0,:,:],cmap='jet',vmin=v_min,...
vmax=v_max,origin='lower', extent = extent_dim)

plt.title('Type:  %s  Freq: %.3e Hz' %(Type,data_dict['freq'][0]) )
plt.xticks(Xlocs, Xlabels)
plt.yticks(Ylocs,Ylabels)
4

2 に答える 2

12

matplotlib最初のアーキテクチャを少し理解する必要があります(創設者で現在の主任開発者による長い記事については、こちらを参照してください)。backendレンダリングとハードウェアとの通信を処理するレイヤーの下部。そのレイヤーの上には、オブジェクトに何をすべきかをartists伝えることで、自分自身を描く方法を知っている人がいます。backendその層の上には、を模倣するpyplot ステート マシンMATLABインターフェイスがあります。

図に表示されるものはすべて として内部的に表され、Artistアーティストは他のアーティストを含むことができます。たとえば、AxesオブジェクトArtistsは、軸の背骨、目盛り、ラベル、線、または画像などである子を追跡し、Axesオブジェクトはオブジェクトの子Figureです。Figure に自分自身を描画するように ( 経由でfig.canvas.draw()) 指示すると、すべての子アーティストが再帰的に描画されます。

この設計の欠点のArtist1 つは、オブジェクトを作成して再利用し続けることができないため、AxesImageオブジェクトを作成して再利用できないことです。

このデザインはまた、Artists知っていることを分離します。 Axesオブジェクトは、目盛りの位置やラベル、表示範囲などを知っています (これはオブジェクトについて知ることによって行われAxisますが、それはさらに雑草に入り込んでいます)。vminやのようなものは、が追跡する( doc ) オブジェクトにvmaxカプセル化されます。これは、リストにあるすべてのものをどのように処理するかを分離する必要があることを意味します。NormalizeAxesImage

ここで工場のようなパターンを使用するか、カレーのようなパターンを使用することをお勧めします

工場ライク:

def set_up_axes(some, arguements):
    '''
    Factory to make configured axes (
    '''
    fig, ax = plt.subplots(1, 1) # or what ever layout you want
    ax.set_*(...)
    return fig, ax


my_norm = matplotlib.colors.Normalize(vmin, mmax) # or write a factory to do fancier stuff
fig, ax = set_up_axes(...)
ax.imshow(..., norm=my_norm)
fig2, ax2 = set_up_axes(...)
ax2.imshow(..., norm=mynorm)

kwargs のセット全体をラップして、それらをそのまま簡単に再利用できます。

my_imshow_args = {'extent':[...],
                  'interpolation':'nearest',
                  'norm': my_norm,
                   ...}

ax2.imshow(..., **my_imshow_args)

カレー風:

def my_imshow(im, ax=None, *args, **kwargs):
    if ax is None:
        ax = plt.gca()
    # do all of your axes set up
    ax.set_xlim(..)

    # set default vmin and vmax
    # you can drop some of these conditionals if you don't want to be
    # able to explicitly override the defaults
    if 'norm' not in kwargs:
        vmin = kwargs.pop('vmin', None)
        vmax = kwargs.pop('vmax', None)
        if vmin is None:
            vmin = default_vmin # or what ever
        if vmax is None:
            vmax = default_vmax
        my_norm = matplotlib.colors.Normalize(vmin, mmax)
        kwargs['norm'] = norm

    # add a similar block for `extent` 
    # or any other kwargs you want to change the default of

    ax.figure.canvas.draw() # if you want to force a re-draw
    return ax.imshow(im, *args, **kwargs)

超賢くなりたい場合はplt.imshow、自分のバージョンにモンキー パッチを適用できます

plt.imshow = my_imshow

の多くの部分のデフォルト値をグローバルな方法で変更できるrcParamsインターフェイスもありますmatplotlib

そして、これを達成するためのさらに別のpartial方法 (を介して)

于 2013-08-18T17:55:43.263 に答える
2

プロットを表示するには、クラスのインスタンスであるfig.canvas.draw()whereを使用します。対話型シェル (読み取り: ) 関数の API バージョンです。figFigurefig.canvas.draw()pylabdraw()

オブジェクトからAxesまたはを取得する必要がある場合は、それぞれまたはを呼び出すことができます。FigureAxesImageim.get_axes()im.get_figure()

「優れた」オブジェクト指向コードを作成する限り、ユーザー インターフェイスの例から始めるのがよいでしょう。

于 2013-08-18T00:30:52.600 に答える