【问题标题】:How to map mouse position on a scatterplot?如何在散点图上映射鼠标位置?
【发布时间】:2020-01-03 06:27:33
【问题描述】:

我正在尝试创建一个多边形区域来选择散点图上的点。问题是我不知道如何在散点图上映射鼠标位置。

我使用了mapFromDevice,但是结果不理想,因为位置是四舍五入的,不精确(我猜这是因为它适应了散点图坐标系)。

我不知道我是否使用了不好的方法。

from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
import pyqtgraph as pg
import sys

class MVAQPlot(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.resize(600,600)
        pg.setConfigOption('background', 'w')
        pg.setConfigOption('foreground', 'k')

        self._graphics_layout = pg.GraphicsLayoutWidget(self)
        layout = QHBoxLayout()
        layout.addWidget(self._graphics_layout)
        self.setLayout(layout)

        self._scores = ([1, 1.5, 3, 5, 5], [1, 1.5, 3.4, 4, 2])

        self._roi = pg.PolyLineROI([], pen=(5))
        self._scatter_plot = pg.ScatterPlotItem()
        self._scatter_plot.setData(self._scores[0], self._scores[1])
        plot = self._graphics_layout.addPlot()
        plot.addItem(self._scatter_plot)
        plot.addItem(self._roi)

        self._selection_timer = QtCore.QTimer()
        self._selection_timer.timeout.connect(self.update_selection)

        self._creating_region = False
        self._last_point = None

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            if self._creating_region:
                self._creating_region = False
                self._selection_timer.stop()
                roi_shape = self._roi.mapToItem(self._scatter_plot, self._roi.shape())
                self._points = list()
                for i in range(len(self._scores[0])):
                    self._points.append(QtCore.QPoint(self._scores[0][i], self._scores[1][i]))
                selected = [roi_shape.contains(pt) for pt in self._points]
                print('Selected points: ' + str(selected))
                self._roi.clearPoints()
            else:
                self._creating_region = True
                self._selection_points = list()
                self._selection_timer.start(1000)

    def update_selection(self):
        if self._roi is not None:
            point = QtCore.QPoint(self._graphics_layout.lastMousePos[0],
                                  self._graphics_layout.lastMousePos[1])
            self._selection_points.append(point)
            region = QtGui.QPolygon(self._selection_points)
            mapped_point = self._scatter_plot.mapFromDevice(region)
            self._roi.setPoints(mapped_point)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    widget = MVAQPlot()
    widget.show()
    sys.exit(app.exec_())

我不知道如何在散点图上绘制精确的 PolyLineROI。像这样的:

【问题讨论】:

  • 如果你使用 matplotlib,你可以只做 pts = plt.ginput(number_of_clicks) 或者在循环中添加一个转义来获得尽可能多的数据。也许你的 pkg 有类似的东西?
  • 我得到一个错误:AttributeError: 'MVAQPlot' object has no attribute '_points'
  • 对不起。我不确定为什么它对我有用。它现在应该可以工作了。
  • @NDA 我点击什么都没有,QTimer 的目的是什么?
  • @eyllanesc 在散点图上单击鼠标左键,每秒(或 QTimer 值)将一个新点添加到 ROI。当您想停止选择时,再次单击鼠标左键。 link

标签: python pyqt pyqtgraph


【解决方案1】:

问题是您使用的 QPointQPolygon 仅支持整数,如果您传递浮点数,则将其舍入。解决方法是使用QPointFQPolygonF

def update_selection(self):
    if self._roi is not None:
        point = QtCore.QPointF(
            self._graphics_layout.lastMousePos[0],
            self._graphics_layout.lastMousePos[1],
        )
        self._selection_points.append(point)
        region = QtGui.QPolygonF(self._selection_points)
        mapped_point = self._scatter_plot.mapFromDevice(region)
        self._roi.setPoints(mapped_point)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    相关资源
    最近更新 更多