Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过移动曲线上的点来更新曲线_Python - Fatal编程技术网

Python 通过移动曲线上的点来更新曲线

Python 通过移动曲线上的点来更新曲线,python,Python,我有一些嘈杂的数据,我想用高斯分布拟合。问题是我必须手动操作。我的意思是,我必须移动曲线上的点(参见下图)。当我移动点时,我必须更新曲线,使曲线可以自行移动 例如,在这个曲线上,如果我移动上面的点,它改变了我的高斯的MU,如果我在中间移动点,它就更新sigma参数。在本例中,我在matplotlib的FigureCanvas中绘制了两条曲线,该matplotlib嵌入在QMainWindow中 我在PyQt小部件中嵌入的matplotlib图形中搜索并发现没有办法做到这一点。所以,我已经改变并

我有一些嘈杂的数据,我想用高斯分布拟合。问题是我必须手动操作。我的意思是,我必须移动曲线上的点(参见下图)。当我移动点时,我必须更新曲线,使曲线可以自行移动

例如,在这个曲线上,如果我移动上面的点,它改变了我的高斯的MU,如果我在中间移动点,它就更新sigma参数。在本例中,我在matplotlib的FigureCanvas中绘制了两条曲线,该matplotlib嵌入在QMainWindow中

我在PyQt小部件中嵌入的matplotlib图形中搜索并发现没有办法做到这一点。所以,我已经改变并尝试将PyQtGraph与ROI工具结合使用,但效果不太好

你知道我怎样才能做到这一点吗?是否有一个简单的python库来实现这一点?谢谢

编辑: 下面是我用来生成图像的代码:

from PySide2 import QtCore, QtGui, QtWidgets

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np


class PainterCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        self._instructions = []
        self.axes = self.figure.add_subplot(111)

    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        width, height = self.get_width_height()
        for x, y, rx, ry, br_color in self._instructions:
            x_pixel, y_pixel_m = self.axes.transData.transform((x, y))
            # In matplotlib, 0,0 is the lower left corner,
            # whereas it's usually the upper right
            # for most image software, so we'll flip the y-coor
            y_pixel = height - y_pixel_m
            painter.setBrush(QtGui.QColor(br_color))
            painter.drawEllipse( QtCore.QPoint(x_pixel, y_pixel), rx, ry)

    def create_oval(self, x, y, radius_x=2, radius_y=2, brush_color="red"):
        self._instructions.append([x, y, radius_x, radius_y, brush_color])
        self.update()


class MyPaintWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.canvas = PainterCanvas()
        self.canvas.mpl_connect("button_press_event", self._on_left_click)
        x = np.arange(0, 10, 0.1)
        rand = [np.random.uniform(-0.1, 0.2) for _ in x]
        y0 = np.exp(- (x - 5) ** 2 / 2) + rand
        y1 = np.exp(- (x - 3) ** 2 / 0.5)
        self.canvas.axes.plot(x, y0)
        self.canvas.axes.plot(x, y1)

        layout_canvas = QtWidgets.QVBoxLayout(self)
        layout_canvas.addWidget(self.canvas)

        self.canvasMenu = QtWidgets.QMenu(self)
        self.canvasMenu.addAction("test")

        self.canvas.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.canvas.customContextMenuRequested.connect(self._on_left_click)

    def _on_left_click(self, event):
        self.canvas.create_oval(event.xdata, event.ydata, brush_color="green")


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    w = MyPaintWidget()
    w.show()
    sys.exit(app.exec_())


为了添加点,我通过单击曲线添加了点。我知道代码不能满足我的要求,但它只是生成一个图像来解释我的想法。

正如mkrieger1所建议的,我将简要描述我的解决方案:

  • 首先,我使用PyQtGraph绘制数据,以比使用Matplotlib时更高效地绘制更新

  • 为了控制曲线,我使用了QSliders(修改为支持double)来控制每条曲线的参数。当我移动一个滑块时,它会发出一个事件,在处理该事件的函数中,我用函数setData更新pyqtgraph plotwidget

我的灵感来自于做双光标: 我使用了pyqtgraph文档:

有太多的代码放在那里,但解决方案在我的GitHub上的spectrofit项目中:(它是处理和研究恒星光谱的UI)。解决方案位于spectrofit.tools.Interactive_Fit.py文件中


希望这能有所帮助

你是如何做到这一点的?我已经添加了用于生成图像的代码。但这段代码只是一个生成图像来解释和说明我的想法的示例。我最终获得了我想要的东西,使用Qsliders来控制曲线的参数,并且我使用pyqtgraph来非常快速地绘制和刷新数据。您可以添加一个解释您的解决方案的答案,这样也将在将来帮助其他人。