其他分享
首页 > 其他分享> > 带有可单击和可选点的PyQt4散点图

带有可单击和可选点的PyQt4散点图

作者:互联网

我正在尝试以一种方式创建一个散点图,该散点图具有大约1000个数据点,以便可以通过使用鼠标单击来选择每个数据点,这将导致弹出一个上下文菜单,该菜单将允许用户删除或更改数据点的颜色.我一直在关注matplotlib的教程,并查看可拖动的矩形练习,但是我遇到了困难.我正在使用matplotlib.patches.Circle类来表示每个数据点,但无法使“包含”方法与“ button_press_event”一起正常工作.主要是,似乎没有与每个Circle对象相关联的“画布”对象.我在第16行收到以下错误:

AttributeError: 'NoneType' object has no attribute 'canvas'

这是代码:

#!/usr/bin/python -tt

import sys
import numpy
#import matplotlib.pyplot
from PyQt4 import QtGui, QtCore
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.patches import Circle

class SelectablePoint:
    def __init__(self, xy, label):
        self.point = Circle( (xy[0], xy[0]), .005 )
        self.label = label
        self.point.figure
        self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.onClick)

    def onClick(self, e):

        print e.xdata, e.ydata
        #print(dir(self.point))
        print self.point.center
        print self.point.contains(e)[0]
        #if self.point.contains(e)[0]:
        #    print self.label


class ScatterPlot(FigureCanvas):
    '''
    classdocs
    '''

    def __init__(self, parent=None):
        '''
        Constructor
        '''

        self.fig = Figure()
        FigureCanvas.__init__(self, self.fig)

        self.axes = self.fig.add_subplot(111)
        #x = numpy.arange(0.0, 3.0, 0.1)
        #y = numpy.cos(2*numpy.pi*x)
        x = [.5]
        y = [.5]

        #scatterplot = self.axes.scatter(x,y)

        for i in range(len(x)):
            c = Circle( (x[i], y[i]), .05 )
            self.axes.add_patch(c)
            #SelectablePoint( (x[i],y[i]), 'label for: ' + str(i), self.figure.canvas )
            SelectablePoint( (x[i],y[i]), 'label for: ' + str(i) )
            #self.axes.add_artist(c)

class MainContainer(QtGui.QMainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.resize(900,600)
        self.setWindowTitle('Scatter Plot')

        sp = ScatterPlot(self)
        self.setCentralWidget(sp)

        self.center()

    def center(self):
        # Get the resolution of the screen
        screen = QtGui.QDesktopWidget().screenGeometry()

        # Get the size of widget
        size = self.geometry()
        self.move( (screen.width() - size.width())/2, (screen.height() - size.height())/2 )

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    b = MainContainer()
    b.show()
    sys.exit(app.exec_())

我不确定是否要采用正确的方法,还是应该查看其他图形模块,但是我已经看过gnuplot和chaco,我觉得matplotlib更适合我的问题.还有其他建议吗?非常感谢你.

**我的解决方案**

到目前为止,这是我的工作.单击散点图中的点时,它仅将每个数据点的标签输出到标准输出.

#!/usr/bin/python -tt

import sys
import numpy
from PyQt4 import QtGui, QtCore
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.patches import Circle

class SelectablePoint:
    def __init__(self, xy, label, fig):
        self.point = Circle( (xy[0], xy[1]), .25, figure=fig)
        self.label = label
        self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.onClick)

    def onClick(self, e):
        if self.point.contains(e)[0]:
            print self.label


class ScatterPlot(FigureCanvas):
    '''
    classdocs
    '''

    def __init__(self, parent=None):
        '''
        Constructor
        '''

        self.fig = Figure()
        FigureCanvas.__init__(self, self.fig)

        self.axes = self.fig.add_subplot(111)
        xlim = [0,7]
        ylim = [0,7]
        self.axes.set_xlim(xlim)
        self.axes.set_ylim(ylim)
        self.axes.set_aspect( 1 )

        x = [1, 1.2, 3, 4, 5, 6]
        y = [1, 1.2, 3, 4, 5, 6]
        labels = ['1', '2', '3', '4', '5', '6']

        for i in range(len(x)):
            sp = SelectablePoint( (x[i],y[i]), labels[i], self.fig)
            self.axes.add_artist(sp.point)

class MainContainer(QtGui.QMainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.resize(900,600)
        self.setWindowTitle('Scatter Plot')

        sp = ScatterPlot(self)
        self.setCentralWidget(sp)

        self.center()

    def center(self):
        # Get the resolution of the screen
        screen = QtGui.QDesktopWidget().screenGeometry()

        # Get the size of widget
        size = self.geometry()
        self.move( (screen.width() - size.width())/2, (screen.height() - size.height())/2 )

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    b = MainContainer()
    b.show()
    sys.exit(app.exec_())

解决方法:

糟糕,我正在创建两个patch实例.为每个数据点绘制圆圈.在将第一个实例传递给我的SelectablePoint类之后,一切正常.

标签:scatter-plot,clickable,matplotlib,pyqt4,python
来源: https://codeday.me/bug/20191208/2093388.html