2014-05-14 2 views
2

분산 형 플롯 점에서 데이터를 선택한 다음 배열에 저장할 수있는 programe/function을 구현하고 싶습니다. 시작하는 방법이나 주제에 대해 더 자세히 알 수있는 방법에 대한 팁은 유용 할 것입니다. :).분산 형 플롯에서 배열 만들기

+2

http://matplotlib.org/1.3.1/api/widgets_api.html 포인트 선택을 시작하는 것이 처음입니다. 이 질문은 당신이 도움이 필요한 구체적인 것이 없으면 아마 닫힐 것입니다. – M4rtini

+0

mpldatacursor – tacaswell

+0

백엔드 'wx'를 기반으로 한 대답과 비슷한 질문이 [here] (http://stackoverflow.com/questions/14525379/selecting-points-from-a-graph-matplotlib)입니다. 그러나 위젯을 사용하여 백엔드 독립적 인 예를 보는 것이 좋을 것입니다. 이것은 모두 매우 일반적인 작업입니다. – gg349

답변

0

올가미 또는 사각형 선택으로 선택하십시오. 상당히 쉽게 확장 할 수 있어야합니다. matplotlib 위젯 만 사용.

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.widgets import Button, LassoSelector, RectangleSelector 
from matplotlib.path import Path 
from matplotlib.patches import Rectangle 
from functools import partial 

class LassoSelect(object): 

    def __init__(self, ax, collection): 
     self.canvas = ax.figure.canvas 
     self.collection = collection 
     self.xys = collection.get_offsets() 
     self.lasso = LassoSelector(ax, onselect=self.onselect) 
     self.setActive(False) 

    def onselect(self, verts): 
     path = Path(verts) 
     ind = np.nonzero([path.contains_point(xy) for xy in self.xys])[0] 
     fc = self.collection.get_facecolors() 
     fc[ind, -1] = 1 
     self.collection.set_facecolors(fc) 
     self.canvas.draw_idle() 

    def setActive(self, activate): 
     if activate: 
      self.lasso.active = True 
     else: 
      self.lasso.active = False 


class RectangleSelect(object): 

    def __init__(self, ax, collection): 
     super(RectangleSelect, self).__init__() 
     self.RS = RectangleSelector(ax, self.onselect, 
            drawtype='box', useblit=True, 
            button=[1, 3], # don't use middle button 
            minspanx=5, minspany=5, 
            spancoords='pixels') 

     self.canvas = ax.figure.canvas 
     self.collection = collection 
     self.xys = collection.get_offsets() 
     self.setActive(False) 

    def onselect(self, eclick, erelease): 
     'eclick and erelease are the press and release events' 
     x1, y1 = eclick.xdata, eclick.ydata 
     x2, y2 = erelease.xdata, erelease.ydata 
     x0 = min(x1, x2) 
     y0 = min(y1, y2) 
     width = abs(x2-x1) 
     height = abs(y2-y1) 
     rect = Rectangle((x0, y0), width, height) 

     ind = np.nonzero([rect.contains_point(xy) for xy in self.xys])[0] 
     fc = self.collection.get_facecolors() 
     fc[ind, -1] = 1 
     self.collection.set_facecolors(fc) 
     self.canvas.draw_idle() 

    def setActive(self, activate): 
     if activate: 
      self.RS.set_active(True) 
     else: 
      self.RS.set_active(False) 


class DataSelector(object): 

    activeColor = (0, 1, 0) 
    inActiveColor = (1, 1, 1) 

    def __init__(self, x, y): 
     super(DataSelector, self).__init__() 
     self.x, self.y = x, y 
     self.fig, self.ax = plt.subplots() 
     self.pts = self.ax.scatter(x, y) 
     self.selected_pts = [] 
     self.addButtons() 
     self.selectorWidgets = {'Rectangle': RectangleSelect(self.ax, self.pts), 
           'Lasso': LassoSelect(self.ax, self.pts)} 

     self.fc = self.pts.get_facecolors() 
     if len(self.fc) == 0: 
      raise ValueError('Collection must have a facecolor') 
     elif len(self.fc) == 1: 
      self.fc = np.tile(self.fc, len(x)).reshape(len(x), -1) 
     self.fc[:, -1] = 0.3 
     self.pts.set_facecolors(self.fc) 

    def resetSelection(self, event=None): 
     self.fc[:, -1] = 0.3 
     self.fig.canvas.draw() 

    def exportSelection(self, event=None): 
     ind = np.nonzero(self.fc[:, -1] != 0.3)[0] 
     print self.x[ind], self.y[ind] 

    def activateWidget(self, key, event): 
     for widgetKey, widget in self.selectorWidgets.iteritems(): 
      if widgetKey == key: 
       widget.setActive(True) 
      else: 
       widget.setActive(False) 
     for ax, button in self.buttonAxes.iteritems(): 
      if ax == event.inaxes: 
       button.color = self.activeColor 
      else: 
       button.color = self.inActiveColor 
      button.hovercolor = button.color 

    def addButtons(self): 
     fig = self.fig 
     fig.subplots_adjust(bottom=0.25) 

     #Button text and callback 
     buttons = [("Lasso", None), ("Rectangle", None), ('Reset', self.resetSelection), ('Export Selection', self.exportSelection)] 

     nButtons = len(buttons) 
     axBorders = np.linspace(0.25, 0.90, nButtons+1, endpoint=False) 
     spacing = axBorders[1] - axBorders[0] 
     self.buttonAxes = {} 
     for i, btn in zip(axBorders, buttons): 
      #[left, bottom, width, height] 
      buttonAx = plt.axes([i, 0.1, spacing, 0.04]) 
      button = Button(buttonAx, btn[0], color=self.inActiveColor) 
      if btn[1] is None: 
       button.on_clicked(partial(self.activateWidget, btn[0])) 
      else: 
       button.on_clicked(btn[1]) 
      self.buttonAxes[buttonAx] = button 

x, y = np.random.random((2, 25))*10 

dataSelector = DataSelector(x, y) 
plt.show() 
관련 문제