2016-03-21 4 views
0

matplotlibからimshow()を使ってプロットしている2D配列のカラーポットでポイントを選択するのにお手伝いできます。 http://matplotlib.org/examples/widgets/lasso_selector_demo.html http://matplotlib.org/examples/event_handling/lasso_demo.htmlpythonの点を選択するlassoまたはlassomanagerを持つimshow()プロット

残念ながら、私は彼らが関数imshowと2D(通常は50x500)の配列を私のために働くことはできません。 私はmatplotlibのから投げ縄やLassoSelectorを使用して2つの例を見つけました。例はうまくいきますが、imshowを使用すると、pythonは色を設定できないなどの不満があります。 私はまだかなり新しいpythonです。私が理解しているところから、imshowに送るデータからコレクションを取得する必要がありますか? 以下は、うまくいかないコード例です。上記の両方の例を成功させてみました。 誰かが正しい方向に私を指し示すことができれば幸いですが、私は働くコードのどちらも気にしません:) ありがとう。

import numpy as np 
import matplotlib.pyplot as plt 
# use random sample data: 
random_data = np.random.rand(5, 5) 
fig, ax = plt.subplots() 
# Need the plot data as collection to be used with the lasso? 
pts = ax.add_collection(imshow(data, aspect='auto', origin='lower',picker=True),autolim=False) 
data = [Datum(*xy) for xy in random_data] 
lman = ps.LassoManager(ax, data) 

ここで上に連結された例からコード:

from matplotlib.widgets import Lasso 
from matplotlib.colors import colorConverter 
from matplotlib.collections import RegularPolyCollection 
from matplotlib import path 

import matplotlib.pyplot as plt 
from numpy import nonzero 
from numpy.random import rand 


class Datum(object): 
    colorin = colorConverter.to_rgba('red') 
    colorout = colorConverter.to_rgba('blue') 

    def __init__(self, x, y, include=False): 
     self.x = x 
     self.y = y 
     if include: 
      self.color = self.colorin 
     else: 
      self.color = self.colorout 


class LassoManager(object): 
    def __init__(self, ax, data): 
     self.axes = ax 
     self.canvas = ax.figure.canvas 
     self.data = data 

     self.Nxy = len(data) 

#  facecolors = [d.color for d in data] 
     self.xys = [(d.x, d.y) for d in data] 
     self.ind = [] 
     fig = ax.figure 
     self.collection = RegularPolyCollection(
      fig.dpi, 6, sizes=(100,), 
      facecolors=facecolors, 
      offsets=self.xys, 
      transOffset=ax.transData) 

     ax.add_collection(self.collection) 

     self.cid = self.canvas.mpl_connect('button_press_event', self.onpress) 

    def callback(self, verts): 
     facecolors = self.collection.get_facecolors() 
     p = path.Path(verts) 
     ind = p.contains_points(self.xys) 
     self.ind = nonzero([p.contains_point(xy) for xy in self.xys])[0] 
     for i in range(len(self.xys)): 
      if ind[i]: 
       facecolors[i] = colorConverter.to_rgba('red') 
#    print ind 
      else: 
       facecolors[i] = colorConverter.to_rgba('blue') 

     self.canvas.draw_idle() 
     self.canvas.widgetlock.release(self.lasso) 
     del self.lasso 

    def onpress(self, event): 
     if self.canvas.widgetlock.locked(): 
      return 
     if event.inaxes is None: 
      return 
     self.lasso = Lasso(event.inaxes, 
          (event.xdata, event.ydata), 
          self.callback) 
     # acquire a lock on the widget drawing 
     self.canvas.widgetlock(self.lasso) 

if __name__ == '__main__': 
    print 'test' 

    data = [Datum(*xy) for xy in rand(5, 5)] 

    ax = plt.axes(xlim=(0, 1), ylim=(0, 1), autoscale_on=False) 
    lman = LassoManager(ax, data) 

    plt.show() 

    for i in lman.ind: 
     print lman.xys[i] 

    print len(lman.xys) 

編集:私は2次元プロット(散乱又はXYプロットせず)からの任意の形状の領域を選択するために以下の例が動作します。あまりにもエレガントではありませんが、それは待つことができます:

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.widgets import LassoSelector 
from matplotlib.path import Path 


data = np.random.rand(10, 5) 
grid = np.indices(data.shape) 

ax = plt.subplot(111) 
ax.pcolormesh(data) 
ind = [] 

def onselect(verts): 
    global ind 
# print verts 
    pp = Path(verts) 
    grid = [(i,j) for j in xrange(int(data.shape[0])) for i in xrange(int(data.shape[0]))] 
    ii = np.nonzero([pp.contains_point(xy) for xy in grid]) 
    ind = [grid[i] for i in ii[0]] 

# ind = pp.contains_points(grid) 
# print ind 
lasso = LassoSelector(ax, onselect) 

plt.draw() 
plt.show() 

print ind 
+0

はあなたがのように外にデータをやり取りし、取得したい意味しますか://stackoverflow.com/questions/33231120/interaction-with-pythons-matplotlib-figure-assign-value-to-selected-features/33231600#33231600 – Chiel

+0

ありがとう、それは正しい方向に私を指摘したデモの例ではなく、Lassoの基本的なonselect関数に戻ります)。私は任意/不規則な形を選択したいので、上記の例を加えたLassoウィジェットを貼りました。 – Seb

答えて

0

コードに定義されていないことがあります。しかし、いずれにせよ、これはあなたが与えたものを使用して機能的な例であるに:

from matplotlib.widgets import Lasso 
from matplotlib.colors import colorConverter 
from matplotlib.collections import RegularPolyCollection 
from matplotlib import path 

import matplotlib.pyplot as plt 
from numpy import nonzero 
from numpy.random import rand 

class Datum(object): 
    colorin = colorConverter.to_rgba('red') 
    colorout = colorConverter.to_rgba('blue') 

    def __init__(self, x, y, include=False): 
     self.x = x 
     self.y = y 
     if include: 
      self.color = self.colorin 
     else: 
      self.color = self.colorout 


class LassoManager(object): 
    def __init__(self, ax, data): 
     self.axes = ax 
     self.canvas = ax.figure.canvas 
     self.data = data 

     self.Nxy = len(data) 

     facecolors = [d.color for d in data] 
     self.xys = [(d.x, d.y) for d in data] 
     self.ind = [] 
     fig = ax.figure 
     self.collection = RegularPolyCollection(
      fig.dpi, 6, sizes=(100,), 
      facecolors=facecolors, 
      offsets=self.xys, 
      transOffset=ax.transData) 

     ax.add_collection(self.collection) 

     self.cid = self.canvas.mpl_connect('button_press_event', self.onpress) 

    def callback(self, verts): 
     facecolors = self.collection.get_facecolors() 
     p = path.Path(verts) 
     ind = p.contains_points(self.xys) 
     self.ind = nonzero([p.contains_point(xy) for xy in self.xys])[0] 
     for i in range(len(self.xys)): 
      if ind[i]: 
       facecolors[i] = colorConverter.to_rgba('red') 
#    print ind 
      else: 
       facecolors[i] = colorConverter.to_rgba('blue') 

     self.canvas.draw_idle() 
     self.canvas.widgetlock.release(self.lasso) 
     del self.lasso 

    def onpress(self, event): 
     if self.canvas.widgetlock.locked(): 
      return 
     if event.inaxes is None: 
      return 
     self.lasso = Lasso(event.inaxes, 
          (event.xdata, event.ydata), 
          self.callback) 
     # acquire a lock on the widget drawing 
     self.canvas.widgetlock(self.lasso) 

data = np.random.rand(5, 5) 
fig, ax = plt.subplots() 
# No, no need for collection 
ax.imshow(data, aspect='auto', origin='lower',picker=True) 
data = [Datum(*xy) for xy in rand(10, 2)] 
lman = LassoManager(ax, data) 
plt.show() 

、ここでの結果は次のとおりです。http:

enter image description here

+0

ありがとうございました。残念なことに、私は十分に私の質問ではっきりと私がプロットしたいデータの定義を混乱させた。この例は102配列(通常の散布図、xyプロット)で動作しますが、私のデータは2次元カラープロットです。データを例えばに変更すると5x5、私はもはやDatumを作成することができないので、例は動作しません。 – Seb

+0

それはプロットとは関係ありません。データムの定義には、定義内にxとyがあります(2つの変数)。 「データ」を5x5にすると、5つの変数がDatumに与えられます。そのため、エラーが表示されます。 – armatita

+0

あなたは正しいです、それは実際にプロットの問題ではなく、私が見つけたサンプルのデータ構造です。 – Seb

関連する問題