Python 从散点图构建阵列

Python 从散点图构建阵列,python,graph,matplotlib,Python,Graph,Matplotlib,我想实现一个程序/函数,从散点图中选择数据,然后将它们存储到数组中。任何关于如何开始或在何处找到更多主题的提示都很好:)。通过套索或矩形选择进行选择。应该很容易扩展。仅使用matplotlib小部件 import numpy as np import matplotlib.pyplot as plt from matplotlib.widgets import Button, LassoSelector, RectangleSelector from matplotlib.path import

我想实现一个程序/函数,从散点图中选择数据,然后将它们存储到数组中。任何关于如何开始或在何处找到更多主题的提示都很好:)。

通过套索或矩形选择进行选择。应该很容易扩展。仅使用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()

让点可以选择将是一个开始。除非您有更具体的问题需要帮助,否则此问题可能会关闭。另请参阅mpldatacursora类似问题,其答案基于后端
wx
,是。不过,如果能看到一个独立于后端、使用小部件的示例,那就太好了。这毕竟是一项非常普通的任务。