2

matplotlib LassoSelector を使用して、散布図からいくつかの点を選択し、選択した点のみに対して別の図を作成しようとしています。2 番目のプロットで別の matplotlib ウィジェットを使用しようとすると、機能しませんが、エラーや警告メッセージは表示されません。以下は、LassoSelector と SpanSelector を使用した最小限の例です。

他のウィジェットも試しました。Button ウィジェットはボタンを表示しますが、ボタンを押したときのアクションは実行されません。

import numpy as np
from matplotlib.pyplot import *
from matplotlib.widgets import SpanSelector, LassoSelector
from matplotlib.path import Path

def onselect(verts):
    global xys,data

    #get indexes of selected points
    path = Path(verts)
    xysn = xys.get_offsets()
    ind = np.nonzero([path.contains_point(xy) for xy in xysn])[0]

    #plot the second figure
    fig=figure(2)
    ax=fig.add_subplot(111)
    ax.hist(data[:,0][ind],10)

    #this should be executed when SpanSelector is used
    def action(min,max):
        print min,max

    #try to do SpanSelector (this fails)
    span=SpanSelector(ax,action,'horizontal')

    show()

#initialize a figure
fig=figure(1)
ax=fig.add_subplot(111)

#create data
data=np.array([[1,6], [4,8],[0,4],[4,2],[9,6],[10,8],[2,2],[5,5],[0,4],[4,5]])

#plot data
xys=ax.scatter(data[:,0],data[:,1])

#select point by drawing a path around them
lasso = LassoSelector(ax, onselect=onselect)

show()
4

1 に答える 1

0

matplotlibウィジェットはイベント ドリブンなので、ユーザーの入力を待ちます。コードの問題は、新しいイベント ハンドラーを使用して新しい図を作成しようとしていることですSpanSelector。以前のイベントの結果として新しいイベントを追加できるかどうかわかりません。SpanSelectorコメントアウトすると、次のエラーが表示されます。

QCoreApplication::exec: The event loop is already running

したがって、新しいイベントLassoSelectorは登録されず、ユーザー入力は取得されません (そして、新しい図は表示されません)。すべての図を作成し、コードの先頭ですべての可能なイベントを登録することをお勧めします。以下は、あなたがやりたいことに近いはずです、

import numpy as np
from matplotlib.pyplot import *
from matplotlib.widgets import SpanSelector, LassoSelector
from matplotlib.path import Path

#this should be executed when LassoSelector is used
def onselect(verts):
    global xys,data

    #get indexes of selected points
    path = Path(verts)
    xysn = xys.get_offsets()
    ind = np.nonzero([path.contains_point(xy) for xy in xysn])[0]

    #Clear and update bar chart
    h, b = np.histogram(data[:,0][ind],10)
    for rect, bars in zip(rects, h):
        rect.set_height(bars)
    ax2.bar(mb, h, align='center')
    draw()

#this should be executed when SpanSelector is used
def action(min,max):
    print min,max

#initialize figures
fig1=figure(1)
ax1=fig1.add_subplot(111)

fig2=figure(2)
ax2=fig2.add_subplot(111)

#create data
data=np.array([[1,6],[4,8],[0,4],[4,2],[9,6],[10,8],[2,2],[5,5],[0,4],[4,5]])

#plot data
xys=ax1.scatter(data[:,0],data[:,1])

#Plot initial histogram of all data
h, b = np.histogram(data[:,0],10)
mb = [0.5*(b[i]+b[i+1]) for i in range(b.shape[0]-1)]
rects = ax2.bar(mb, h, align='center')

#Register lasso selector
lasso = LassoSelector(ax1, onselect=onselect)

#Register SpanSelector 
span=SpanSelector(ax2,action,'horizontal')

show()

棒グラフを更新するには、プロットよりも少しトリッキーなので、ここでこの回答を使用しました

何らかの理由で、ヒストグラムの図 2 は、クリックしたときにのみ更新されます。これには、作業しやすいかもしれない2つの軸を持つ単一の図を使用することを検討します。

fig, ax = subplots(2,1)
ax1 = ax[0]; ax2 = ax[1]
于 2016-07-05T08:24:53.597 に答える