Inset Images into pyside2 from matplotlib

created at 07-29-2021 views: 21

background

I am using PySide2 to make a GUI, and I want to display the graph drawn using Matplotlib in the background on the interface. I found this blog on the Internet to solve my needs. So keep the record of learning the original blogger's program.

1. interface

Use qt designer to design a simple interface

interface from qt designer

There are only two controls, 

  1. Graphics View under Display Widgets, and name the object graphicsView,
  2. Push Button, and name the object btn_sin.

2. inherit FigureCanvas

Define a class that inherits FigureCanvas

import matplotlib
import numpy as np
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt

matplotlib.use("Qt5Agg")  # Declare the use of QT5

class MyFigureCanvas(FigureCanvas):
    """
    By inheriting the FigureCanvas class, this class is both a PyQt5 Qwidget and a matplotlib FigureCanvas, which is the key to connecting pyqt5 and matplotlib
    """

    def __init__(self, parent=None, width=10, height=5, xlim=(0, 2500), ylim=(-2, 2), dpi=100):
         # Initialize the length, width, and pixels of the picture to be given
         # Where xlim, ylim represent the display range of the horizontal and vertical coordinates
         # Create a Figure
        self.figure = plt.Figure(figsize=(width, height), dpi=dpi, tight_layout=True)  # tight_layout: Used to remove the white space on both sides when drawing
        FigureCanvas.__init__(self, self.figure)  
        self.setParent(parent)

        self.fig1 = self.figure.add_subplot(111)  # Add subgraph
        # add_subplot(2,2,4) Add a subgraph function, the three parameters respectively indicate how many subgraphs are divided vertically and several subgraphs horizontally, which is currently the first subgraph
        self.fig1.spines['top'].set_visible(False)  # Remove the horizontal lines on the drawing
        self.fig1.spines['right'].set_visible(False)  # Remove the horizontal line on the right when drawing
        self.fig1.set_xlim(xlim)
        self.fig1.set_ylim(ylim)

With border

Without border

complete code

from PySide2.QtWidgets import QApplication, QMessageBox, QFileDialog, QGraphicsScene
from PySide2.QtUiTools import QUiLoader

import matplotlib
import numpy as np
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt

matplotlib.use("Qt5Agg")  

class MyFigureCanvas(FigureCanvas):


    def __init__(self, parent=None, width=10, height=5, xlim=(0, 2500), ylim=(-2, 2), dpi=100):

        self.figure = plt.Figure(figsize=(width, height), dpi=dpi, tight_layout=True) 
        FigureCanvas.__init__(self, self.figure)  
        self.setParent(parent)

        self.fig1 = self.figure.add_subplot(111)  

        self.fig1.spines['top'].set_visible(False)  
        self.fig1.spines['right'].set_visible(False)  
        self.fig1.set_xlim(xlim)
        self.fig1.set_ylim(ylim)

class Win_Main():
    def __init__(self):

        self.ui = QUiLoader().load("ui_interactive_test2.ui")  

        self.gv_visual_data_content = MyFigureCanvas(width=self.ui.graphicsView.width()/ 100,
                                            height = self.ui.graphicsView.height() / 100,
                                            xlim =(0, 2 * np.pi),
                                            ylim = (-1, 1)
                                            )

        self.plot_cos()
        self.ui.btn_sin.clicked.connect(self.plot_sin)


    def plot_cos(self):
        x = np.arange(0, 2 * np.pi, np.pi / 100)
        y = np.cos(x)
        self.gv_visual_data_content.fig1.plot(x, y)  
        self.gv_visual_data_content.fig1.set_title('cos()') 
        self.graphic_scene = QGraphicsScene() 

        self.graphic_scene.addWidget(self.gv_visual_data_content)
        # Put the graphics in QGraphicsScene, note: the graphics are put into QGraphicsScene as a QWidget
        self.ui.graphicsView.setScene(self.graphic_scene)  # Put QGraphicsScene into QGraphicsView
        self.ui.graphicsView.show()  

    def plot_sin(self):
        x = np.arange(0, 2 * np.pi, np.pi / 100)
        y = np.sin(x)
        self.gv_visual_data_content.fig1.clear() # Since the picture needs to be drawn repeatedly, it is cleared before drawing each time, and then drawing
        self.gv_visual_data_content.fig1.plot(x, y)
        self.gv_visual_data_content.fig1.set_title('sin()')
        self.gv_visual_data_content.draw()  # Refresh the canvas to display the picture, otherwise it will not refresh the display

app = QApplication([])
LoginWin = Win_Main()
LoginWin.ui.show()
app.exec_()
created at:07-29-2021
edited at: 05-31-2022: