Python 在Matplotlib图形上独立添加/删除绘图

Python 在Matplotlib图形上独立添加/删除绘图,python,matplotlib,pyqt5,Python,Matplotlib,Pyqt5,我想生成一个散点图(最多50万个点),并在此基础上添加不同的统计数据(例如,Q1、中值、Q3)。这样做的目的是添加/删除这些统计数据,而无需重新填写散点图,以加快处理过程。到目前为止,我可以在图形上独立添加绘图,但无法删除特定绘图。 当我取消选中该复选框时,会出现以下错误: AttributeError: 'Graphics' object has no attribute 'vline1' 我知道,当我创建绘图时,我需要存储/返回绘图,以便稍后在我要删除它时调用它,但我不知道如何做到这一点

我想生成一个散点图(最多50万个点),并在此基础上添加不同的统计数据(例如,Q1、中值、Q3)。这样做的目的是添加/删除这些统计数据,而无需重新填写散点图,以加快处理过程。到目前为止,我可以在图形上独立添加绘图,但无法删除特定绘图。 当我取消选中该复选框时,会出现以下错误:

AttributeError: 'Graphics' object has no attribute 'vline1'
我知道,当我创建绘图时,我需要存储/返回绘图,以便稍后在我要删除它时调用它,但我不知道如何做到这一点

以下是我当前的代码:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.pyplot import Figure

class Mainwindow(QMainWindow):
    def __init__(self, parent=None):
        super(Mainwindow, self).__init__(parent)

        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)
        self.canvas = FigureCanvas(self.fig)
        self.gridLayout = QGridLayout(centralWidget)
        self.gridLayout.addWidget(self.canvas)   
        self.btn_plot = QCheckBox("Plot")
        self.btn_line = QCheckBox("Line")
        self.gridLayout.addWidget(self.btn_plot, 1,0,1,1)
        self.gridLayout.addWidget(self.btn_line, 2,0,1,1)
        self.btn_plot.clicked.connect(self.btnPlot)
        self.btn_line.clicked.connect(self.btnLine)

    def btnPlot(self):
        self.checked = self.btn_plot.isChecked()
        self.Graphics = Graphics('plot', self.checked, self.axes)

    def btnLine(self):
        self.checked = self.btn_line.isChecked()
        self.Graphics = Graphics('line', self.checked, self.axes)

class Graphics:
    def __init__(self, typeGraph, checked, axes):
        self.typeGraph = typeGraph
        self.checked = checked
        self.axes = axes
        if self.typeGraph == 'plot': self.drawPlot()
        if self.typeGraph == 'line': self.drawLine()

    def drawPlot(self):
        if self.checked == True:
            self.plot = self.axes.plot([10,20,30], [5,10,2], 'o')
        else:
            self.plot.remove()
        self.axes.figure.canvas.draw()

    def drawLine(self):
        if self.checked == True:
            self.vline1 = self.axes.axvline(x=15, linestyle="dashed", color="#595959")
            self.vline2 = self.axes.axvline(x=25, linestyle="dashed", color="#595959")
        else:
            self.vline1.remove()
            self.vline2.remove()
        self.axes.figure.canvas.draw()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    prog = Mainwindow()   
    prog.show()
    sys.exit(app.exec_())

问题在于,当您单击它时,它总是会创建新的
图形
(在
btnPlot
/
btnLine
),而该图形没有以前的值-
绘图、vline1、vline2
。您只需创建一次
图形
,然后仅运行
绘图(选中)
绘图线(选中)
,即可添加或删除项目

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.pyplot import Figure

class Mainwindow(QMainWindow):
    def __init__(self, parent=None):
        super(Mainwindow, self).__init__(parent)

        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)
        self.canvas = FigureCanvas(self.fig)
        self.gridLayout = QGridLayout(centralWidget)
        self.gridLayout.addWidget(self.canvas)   
        self.btn_plot = QCheckBox("Plot")
        self.btn_line = QCheckBox("Line")
        self.gridLayout.addWidget(self.btn_plot, 1,0,1,1)
        self.gridLayout.addWidget(self.btn_line, 2,0,1,1)
        self.btn_plot.clicked.connect(self.btnPlot)
        self.btn_line.clicked.connect(self.btnLine)

        # create only once
        self.Graphics = Graphics(self.axes)

    def btnPlot(self):
        # add or remove 
        self.Graphics.drawPlot(self.btn_plot.isChecked())

    def btnLine(self):
        # add or remove 
        self.Graphics.drawLine(self.btn_line.isChecked())

class Graphics:
    def __init__(self, axes):
        self.axes = axes
        # create at start with default values (but frankly, now I don't need it)
        self.plot = None
        self.vline1 = None
        self.vline2 = None

    def drawPlot(self, checked):
        if checked:
            self.plot = self.axes.plot([10,20,30], [5,10,2], 'o')
        else:
            for item in self.plot:
                item.remove()
        self.axes.figure.canvas.draw()

    def drawLine(self, checked):
        if checked:
            self.vline1 = self.axes.axvline(x=15, linestyle="dashed", color="#595959")
            self.vline2 = self.axes.axvline(x=25, linestyle="dashed", color="#595959")
        else:
            self.vline1.remove()
            self.vline2.remove()
        self.axes.figure.canvas.draw()

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    prog = Mainwindow()   
    prog.show()
    sys.exit(app.exec())

问题在于,当您单击它时,它总是会创建新的
图形
(在
btnPlot
/
btnLine
),而该图形没有以前的值-
绘图、vline1、vline2
。您只需创建一次
图形
,然后仅运行
绘图(选中)
绘图线(选中)
,即可添加或删除项目

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.pyplot import Figure

class Mainwindow(QMainWindow):
    def __init__(self, parent=None):
        super(Mainwindow, self).__init__(parent)

        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)
        self.canvas = FigureCanvas(self.fig)
        self.gridLayout = QGridLayout(centralWidget)
        self.gridLayout.addWidget(self.canvas)   
        self.btn_plot = QCheckBox("Plot")
        self.btn_line = QCheckBox("Line")
        self.gridLayout.addWidget(self.btn_plot, 1,0,1,1)
        self.gridLayout.addWidget(self.btn_line, 2,0,1,1)
        self.btn_plot.clicked.connect(self.btnPlot)
        self.btn_line.clicked.connect(self.btnLine)

        # create only once
        self.Graphics = Graphics(self.axes)

    def btnPlot(self):
        # add or remove 
        self.Graphics.drawPlot(self.btn_plot.isChecked())

    def btnLine(self):
        # add or remove 
        self.Graphics.drawLine(self.btn_line.isChecked())

class Graphics:
    def __init__(self, axes):
        self.axes = axes
        # create at start with default values (but frankly, now I don't need it)
        self.plot = None
        self.vline1 = None
        self.vline2 = None

    def drawPlot(self, checked):
        if checked:
            self.plot = self.axes.plot([10,20,30], [5,10,2], 'o')
        else:
            for item in self.plot:
                item.remove()
        self.axes.figure.canvas.draw()

    def drawLine(self, checked):
        if checked:
            self.vline1 = self.axes.axvline(x=15, linestyle="dashed", color="#595959")
            self.vline2 = self.axes.axvline(x=25, linestyle="dashed", color="#595959")
        else:
            self.vline1.remove()
            self.vline2.remove()
        self.axes.figure.canvas.draw()

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    prog = Mainwindow()   
    prog.show()
    sys.exit(app.exec())

哪一行有问题?关于从图形中删除绘图的一些信息这里有问题,因为当您单击它时,它总是创建新图形(在btnPlot/btnLine中)其中没有以前的值-您应该只创建一次图形。哪一行会产生问题?关于从图形中删除绘图的一些信息可能会出现问题,因为当您单击它时,它总是创建没有以前值的新图形(在btnPlot/btnLine中)-您应该只创建一次图形。