PySide6 and Matplotlib - Simple Line Plot

12/01/2022, Thu
Categories: #python

Fill a Window with a Graph

The PySide6 library offers Python bindings for Qt which is a C++ cross-platform UI library. Qt has been in development for a long time and this will give a stable and mature platform for developing desktop applications. PySide enables one to leverage all the packages from the Python community while using QT. The Python graphing library, Matplotlib, becomes a naturally pairing with the QT library because Matplotlib provides integration options.

To show how Matplotlib can be used with PySide, the below example will demonstrate a plot that scales to the full width and height of a desktop window. We start off by importing the PySide and Matplotlib dependencies along with the native packages to generate data for our graph.

The __init__ function will define a couple of properties to provide the desktop values for window size and title while the PlotCanvas function will be defined later to set up the Matplotlib graph details.

The Qt QVBoxLayout is defined for storing the graph canvas to scale inside the window.

import sys
import random

# PySide dependency
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout

# Matplotlib dependencies
from matplotlib.backends.backend_qtagg import FigureCanvas
from matplotlib.figure import Figure

class App(QWidget):

    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        # Set properties of the window
        self.resize(600, 490)
        self.title = 'The Window Title'
        self.setWindowTitle(self.title)

        # Create the matplotlib canvas
        canvas = PlotCanvas(self)

        # Add the plot canvas to the horizontal box layout
        layout = QVBoxLayout()
        layout.addWidget(canvas)
        self.setLayout(layout)

# ...

Now the PlotCanvas function creates the graph canvas and figure before setting the properties for the graph. Most of the manipulation of the graph involves calling on functions on the self.axes object.

class PlotCanvas(FigureCanvas):
    def __init__(self, parent=None, dpi=100):
        super(PlotCanvas, self).__init__(Figure()) 

        self.setParent(parent)

        # Create the figure and figure canvas
        fig = Figure(dpi=dpi)
        self.figure = fig
        self.canvas = FigureCanvas(self.figure)
        self.axes = fig.add_subplot()

        # Create data for the graph
        data = [random.random() for i in range(25)]

        # Line style
        self.axes.plot(data, linestyle='dashed')

        # Graph title text
        self.axes.set_title('The Graph Title')

        # Axes labels text
        self.axes.set_ylabel('Y Label')
        self.axes.set_xlabel('X Label')

        # X-axis color change
        self.axes.xaxis.label.set_color('blue')

        # Set the x-axis ticks and labels
        self.axes.xaxis.set_tick_params(colors='red')

        # Set y-axis label line color
        self.axes.spines['left'].set_color('orange')
        
        self.draw()

if __name__ == '__main__':
    app = QApplication(sys.argv)

    # Additional styling for the widget which houses
    # the chart
    app.setStyleSheet("""
      QWidget {
        background-color: "green";
        padding: 20px;
      }
    """)

    widget = App()
    widget.show()
    sys.exit(app.exec())

The outcome of all this will result in the graph below.