Python 在tabWidget内的pyqt5中使用matplotlib绘制另一个图形之前未清除图形

Python 在tabWidget内的pyqt5中使用matplotlib绘制另一个图形之前未清除图形,python,matplotlib,pyqt5,Python,Matplotlib,Pyqt5,我正在学习pyqt 5和python,并希望制作一个简单的应用程序,用选项卡、网页和matplotlib图显示布局。当我更改组合框时,我希望在matplotlib图中显示某个国家的形状文件,但是,我只能显示第一个形状文件`下面是显示布局和问题的简化代码,而不是示例中的shapefile。我只是有一些稍微不同的函数,当组合框更改时,这些函数应该更改。但是,只显示第一个图形,尽管变量是从组合框传递的,但新函数不会被绘制出来。基本上,在这一点上,我想做的就是能够下拉组合框选择其他国家,并看到新的图形出

我正在学习pyqt 5和python,并希望制作一个简单的应用程序,用选项卡、网页和matplotlib图显示布局。当我更改组合框时,我希望在matplotlib图中显示某个国家的形状文件,但是,我只能显示第一个形状文件`下面是显示布局和问题的简化代码,而不是示例中的shapefile。我只是有一些稍微不同的函数,当组合框更改时,这些函数应该更改。但是,只显示第一个图形,尽管变量是从组合框传递的,但新函数不会被绘制出来。基本上,在这一点上,我想做的就是能够下拉组合框选择其他国家,并看到新的图形出现。其他建议也受到赞赏。下面是代码示例

import numpy as np
import sys
from PyQt5.QtCore import QUrl,QRect,QSize
from PyQt5.QtWebEngineWidgets import QWebEngineSettings, QWebEngineView, QWebEnginePage 
from PyQt5.QtWidgets import (QApplication, QMainWindow,QMenu,QHBoxLayout,QVBoxLayout,QFrame,QLabel,
QSizePolicy, QMessageBox, QWidget, QPushButton,QRadioButton,
QTextBrowser,QDialog,QGroupBox,QTabWidget,QComboBox,QListWidget)

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import shapefile as shp
import matplotlib.pyplot as plt

import random

data_square=[(0,0),(1,0),(1,1),(0,1),(0,0),(1,1)]
data_rectangle=[(0,0),(2,0),(2,1),(0,1),(0,0),(1,1)]

class MyBrowser(QWebEnginePage):

    def userAgentForUrl(self, url):
        return "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"

class Web(QWebEngineView):

    def load(self, url):
        self.setUrl(QUrl(url))

    def adjustTitle(self):
        self.setWindowTitle(self.title())

    def disableJS(self):
        settings = QWebEngineSettings.globalSettings()
        settings.setAttribute(QWebEngineSettings.JavascriptEnabled, False)




class App(QDialog):
    def __init__(self):
        super().__init__()
        self.title= 'Test Building PyQT5 with Tabs'
        self.left = 40
        self.top = 40
        self.width = 400
        self.height = 100
        self.initUI()


    def initUI(self):        
        #self.setWindowTitle(self.title)
        #self.setGeometry(100,100,1000,800)
        #self.create_my_layout()
        #my_main_window_layout=QVBoxLayout()
        #self.setLayout(my_main_window_layout)
        #self.show()

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.create_my_layout()

        windowLayout = QVBoxLayout()
        #windowLayout.addWidget(self.horizontalGroupBox)
        self.setLayout(windowLayout)

        self.show()

    def my_combo_active(self,index):
        my_specific_country = self.my_combo.itemText(index)
        if my_specific_country=='Afghanistan':
            m = PlotCanvas(self.my_graphic, width=5, height=5, dpi=100,atest='abc',sf=data_square)
            print('A')
        if my_specific_country=='Bangladesh':
            m = PlotCanvas(self.my_graphic, width=5, height=5, dpi=100,atest='def',sf=data_rectangle)
            print('B')


    def create_my_layout(self):
# Set up group boxes along left side of window
        my_groupbox1=QGroupBox('box 1')
        my_groupbox2=QGroupBox('box 2')

        my_button1=QRadioButton('a button')
        my_button1.setChecked(True)
        #radiobutton.toggled.connect(self.on_radio_button_toggled)
        my_button2=QRadioButton('another button')

        my_button5=QRadioButton('more button')
        my_button5.setChecked(True)
        my_button6=QRadioButton('even more button')

        v_box0=QVBoxLayout()
        v_box0.addWidget(my_button1)
        v_box0.addWidget(my_button2)
        my_groupbox1.setLayout(v_box0)

        v_box00=QVBoxLayout()
        v_box00.addWidget(my_button5)
        v_box00.addWidget(my_button6)
        my_groupbox2.setLayout(v_box00)



#set up Tab Widget to end up on right side   
        my_tabWidget=QTabWidget()
        tab1=QWidget()
        tab2=QWidget()

        my_tabWidget.addTab(tab1,"Tab 1")
        my_tabWidget.addTab(tab2,"Tab 2")



# Add To Tab 1
        my_label_country=QLabel('Country')
        my_label_country.setMaximumSize(QSize(1000,50))
        my_label_map=QLabel('Map')

        self.my_combo=QComboBox()
        self.my_combo.activated.connect(self.my_combo_active)
        self.my_graphic=QFrame()
        self.my_graphic.setMinimumSize(QSize(500,500))

        my_list1=QListWidget()
        my_list2=QListWidget()
        my_list3=QListWidget()
        my_button_complete=QPushButton('')
        #my_list4=QListWidget()

        tab1.v_box1=QVBoxLayout()
        tab1.v_box1.addWidget(self.my_combo)
        tab1.v_box1.addWidget(my_label_map)
        tab1.v_box1.addWidget(self.my_graphic)
        tab1.v_box1.addWidget(my_list1)

        tab1.v_box2=QVBoxLayout()
        tab1.v_box2.addWidget(my_list2)

        tab1.v_box3=QVBoxLayout()
        tab1.v_box3.addWidget(my_list3)
        tab1.v_box3.addWidget(my_button_complete)

        tab1.h_box1=QHBoxLayout()
        tab1.h_box1.addLayout(tab1.v_box1)
        tab1.h_box1.addLayout(tab1.v_box2)
        tab1.h_box1.addLayout(tab1.v_box3)

        tab1.setLayout(tab1.h_box1)

# now add Elements to Tab 2 
        my_label_webpage=QLabel('A Web Page')
        my_label_webpage.setMaximumSize(QSize(1000,20))


        #my_combo=QComboBox()
# PC version
        #my_webpage=QWebView()
#Mac version
        my_webpage=Web()
        my_list_exText=QListWidget()



        tab2.v_box1=QVBoxLayout() 
        tab2.v_box1.addWidget(my_webpage)

        tab2.v_box2=QVBoxLayout()
        tab2.v_box2.addWidget(my_list_exText)

        tab2.h_box1=QHBoxLayout()
        tab2.h_box1.addLayout(tab2.v_box1)
        tab2.setLayout(tab2.h_box1)

        my_webpage.load(QUrl("https://google.com"))
        my_webpage.show()


# arrange Group Boxes vertically and Tab on the Right        
        v_box1=QVBoxLayout()
        v_box1.addWidget(my_groupbox1)
        v_box1.addWidget(my_groupbox2)
        v_box2=QVBoxLayout()
        v_box2.addWidget(my_tabWidget)
        h_box1=QHBoxLayout()
        h_box1.addLayout(v_box1)
        h_box1.addLayout(v_box2)   
        self.setLayout(h_box1)

        m = PlotCanvas(self.my_graphic, width=5, height=5, dpi=100,atest='xyz',sf=data_square)

# Fill the ComboBox of Countries
        my_sample_countries= ['Afghanistan','Bangladesh']
        for country in my_sample_countries:
            self.my_combo.addItem(country)

class PlotCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100,atest='xyz',sf=data_square):



        fig = Figure(figsize=(width, height), dpi=dpi)

        axes = fig.add_subplot(111)
        axes.hold(False)

        FigureCanvas.__init__(self, fig)

        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

        ax = self.figure.add_subplot(111)


        x = np.linspace(0, 3 * np.pi, 400)
        y = np.sin(x ** 3) 

        print('atest',atest)

        if atest=='abc':
            x = np.linspace(0, 2 * np.pi, 400)
            y = np.sin(x ** 2)
            print('A case')
        if atest=='def':
            x = np.linspace(0, 4 * np.pi, 400)
            y = np.sin(x ** 4)
            print('B case')

        ax.plot(x,y)        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

必须手动强制绘制图形

ax.figure.canvas.draw()
self.show()
试试看:

import numpy as np
import sys
from PyQt5.QtCore import QUrl,QRect,QSize
from PyQt5.QtWebEngineWidgets import QWebEngineSettings, QWebEngineView, QWebEnginePage 
from PyQt5.QtWidgets import (QApplication, QMainWindow,QMenu,QHBoxLayout,QVBoxLayout,QFrame,QLabel,
        QSizePolicy, QMessageBox, QWidget, QPushButton,QRadioButton,
        QTextBrowser,QDialog,QGroupBox,QTabWidget,QComboBox,QListWidget)

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import shapefile as shp
import matplotlib.pyplot as plt

import random

data_square=[(0,0),(1,0),(1,1),(0,1),(0,0),(1,1)]
data_rectangle=[(0,0),(2,0),(2,1),(0,1),(0,0),(1,1)]

class MyBrowser(QWebEnginePage):

    def userAgentForUrl(self, url):
        return "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"

class Web(QWebEngineView):

    def load(self, url):
        self.setUrl(QUrl(url))

    def adjustTitle(self):
        self.setWindowTitle(self.title())

    def disableJS(self):
        settings = QWebEngineSettings.globalSettings()
        settings.setAttribute(QWebEngineSettings.JavascriptEnabled, False)




class App(QDialog):
    def __init__(self):
        super().__init__()
        self.title= 'Test Building PyQT5 with Tabs'
        self.left   =  40
        self.top    =  40
        self.width  = 400
        self.height = 100
        self.initUI()


    def initUI(self):        
        #self.setWindowTitle(self.title)
        #self.setGeometry(100,100,1000,800)
        #self.create_my_layout()
        #my_main_window_layout=QVBoxLayout()
        #self.setLayout(my_main_window_layout)
        #self.show()

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.create_my_layout()

        windowLayout = QVBoxLayout()
        #windowLayout.addWidget(self.horizontalGroupBox)
        self.setLayout(windowLayout)

        self.show()

    def my_combo_active(self,index):
        my_specific_country = self.my_combo.itemText(index)
        if my_specific_country == 'Afghanistan':
            m = PlotCanvas(self.my_graphic, width=5, height=5, dpi=100,atest='abc',sf=data_square)
            print('A')
        if my_specific_country == 'Bangladesh':
            m = PlotCanvas(self.my_graphic, width=5, height=5, dpi=100,atest='def',sf=data_rectangle)
            print('B')


    def create_my_layout(self):
# Set up group boxes along left side of window
        my_groupbox1=QGroupBox('box 1')
        my_groupbox2=QGroupBox('box 2')

        my_button1=QRadioButton('a button')
        my_button1.setChecked(True)
        #radiobutton.toggled.connect(self.on_radio_button_toggled)
        my_button2=QRadioButton('another button')

        my_button5=QRadioButton('more button')
        my_button5.setChecked(True)
        my_button6=QRadioButton('even more button')

        v_box0=QVBoxLayout()
        v_box0.addWidget(my_button1)
        v_box0.addWidget(my_button2)
        my_groupbox1.setLayout(v_box0)

        v_box00=QVBoxLayout()
        v_box00.addWidget(my_button5)
        v_box00.addWidget(my_button6)
        my_groupbox2.setLayout(v_box00)



#set up Tab Widget to end up on right side   
        my_tabWidget=QTabWidget()
        tab1=QWidget()
        tab2=QWidget()

        my_tabWidget.addTab(tab1,"Tab 1")
        my_tabWidget.addTab(tab2,"Tab 2")



# Add To Tab 1
        my_label_country = QLabel('Country')
        my_label_country.setMaximumSize(QSize(1000,50))
        my_label_map = QLabel('Map')

        self.my_combo = QComboBox()
        self.my_combo.activated.connect(self.my_combo_active)
        self.my_graphic=QFrame()
        self.my_graphic.setMinimumSize(QSize(500,500))

        my_list1 = QListWidget()
        my_list2 = QListWidget()
        my_list3 = QListWidget()
        my_button_complete=QPushButton('')
        #my_list4=QListWidget()

        tab1.v_box1 = QVBoxLayout()
        tab1.v_box1.addWidget(self.my_combo)
        tab1.v_box1.addWidget(my_label_map)
        tab1.v_box1.addWidget(self.my_graphic)
        tab1.v_box1.addWidget(my_list1)

        tab1.v_box2 = QVBoxLayout()
        tab1.v_box2.addWidget(my_list2)

        tab1.v_box3 = QVBoxLayout()
        tab1.v_box3.addWidget(my_list3)
        tab1.v_box3.addWidget(my_button_complete)

        tab1.h_box1 = QHBoxLayout()
        tab1.h_box1.addLayout(tab1.v_box1)
        tab1.h_box1.addLayout(tab1.v_box2)
        tab1.h_box1.addLayout(tab1.v_box3)

        tab1.setLayout(tab1.h_box1)

# now add Elements to Tab 2 
        my_label_webpage=QLabel('A Web Page')
        my_label_webpage.setMaximumSize(QSize(1000,20))


        #my_combo=QComboBox()
# PC version
        #my_webpage=QWebView()
#Mac version
        my_webpage=Web()
        my_list_exText=QListWidget()



        tab2.v_box1=QVBoxLayout() 
        tab2.v_box1.addWidget(my_webpage)

        tab2.v_box2=QVBoxLayout()
        tab2.v_box2.addWidget(my_list_exText)

        tab2.h_box1=QHBoxLayout()
        tab2.h_box1.addLayout(tab2.v_box1)
        tab2.setLayout(tab2.h_box1)

        my_webpage.load(QUrl("https://google.com"))
        my_webpage.show()


# arrange Group Boxes vertically and Tab on the Right        
        v_box1=QVBoxLayout()
        v_box1.addWidget(my_groupbox1)
        v_box1.addWidget(my_groupbox2)
        v_box2=QVBoxLayout()
        v_box2.addWidget(my_tabWidget)
        h_box1=QHBoxLayout()
        h_box1.addLayout(v_box1)
        h_box1.addLayout(v_box2)   
        self.setLayout(h_box1)

        #m = PlotCanvas(self.my_graphic, width=5, height=5, dpi=100,atest='xyz',sf=data_square)
        m = PlotCanvas(self.my_graphic, width=5, height=5, dpi=100,atest='xyz',sf=data_square)

# Fill the ComboBox of Countries
        my_sample_countries= ['Afghanistan','Bangladesh']
        for country in my_sample_countries:
            self.my_combo.addItem(country)

class PlotCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100, atest='xyz', sf=data_square):

        fig = Figure(figsize=(width, height), dpi=dpi)

        axes = fig.add_subplot(111)
        axes.hold(False)

        FigureCanvas.__init__(self, fig)

        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

        ax = self.figure.add_subplot(111)


        x = np.linspace(0, 3 * np.pi, 400)
        y = np.sin(x ** 3) 

        print('atest', atest)

        if atest == 'abc':
            x = np.linspace(0, 2 * np.pi, 400)
            y = np.sin(x ** 2)
            print('A case')
        if atest == 'def':
            x = np.linspace(0, 4 * np.pi, 400)
            y = np.sin(x ** 4)
            print('B case')

        ax.plot(x,y)      
        # have to manually force a figure draw
        ax.figure.canvas.draw()     # +  
        self.show()                 # +       

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

每次选择新国家/地区时,是否需要创建新画布?对我来说,保留一张画布并更改其内容更有意义。我认为你是对的。我我会研究这个方法的。谢谢,我投了更高的票,但自从我是新来的就没有了。我知道我缺少了一些简单而基本的东西……我总是选择在GUI中使用
.draw\u idle()
而不是
.draw()
。虽然在大多数情况下这并不重要,但您永远不知道绘制需要多长时间,因此
draw\u idle()
会更安全。