[Qgis-user] problem with matplotlib in context with QGIS processing plugins

Manfred Strahlhofer manfred.strahlhofer at gmail.com
Tue Feb 14 13:11:27 PST 2023


Hello!

There is a problem when using "matplotlib.backends" and drawing plots when
called from a QGIS processing plugin. I am using the following test code:
# sample code below draws a canvas with a plot
# however closing this plot canvas crashes the plugin (cannot be restarted)
# and further qgis can't be closed with the X button
# originates from:
https://matplotlib.org/stable/gallery/user_interfaces/embedding_in_qt_sgskip.html#sphx-glr-gallery-user-interfaces-embedding-in-qt-sgskip-py
import sys
import time

import numpy as np

from matplotlib.backends.qt_compat import QtWidgets
from matplotlib.backends.backend_qtagg import (
    FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        layout = QtWidgets.QVBoxLayout(self._main)

        static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        # Ideally one would use self.addToolBar here, but it is slightly
        # incompatible between PyQt6 and other bindings, so we just add the
        # toolbar as a plain widget instead.
        layout.addWidget(NavigationToolbar(static_canvas, self))
        layout.addWidget(static_canvas)

        dynamic_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        layout.addWidget(dynamic_canvas)
        layout.addWidget(NavigationToolbar(dynamic_canvas, self))

        self._static_ax = static_canvas.figure.subplots()
        t = np.linspace(0, 10, 501)
        self._static_ax.plot(t, np.tan(t), ".")

        self._dynamic_ax = dynamic_canvas.figure.subplots()
        t = np.linspace(0, 10, 101)
        # Set up a Line2D.
        self._line, = self._dynamic_ax.plot(t, np.sin(t + time.time()))
        self._timer = dynamic_canvas.new_timer(50)
        self._timer.add_callback(self._update_canvas)
        self._timer.start()

    def _update_canvas(self):
        t = np.linspace(0, 10, 101)
        # Shift the sinusoid as a function of time.
        self._line.set_data(t, np.sin(t + time.time()))
        self._line.figure.canvas.draw()


def test_plot():

    # Check whether there is already a running QApplication (e.g., if
running
    # from an IDE).
    #qapp = QtWidgets.QApplication.instance()   this stucks QGIS!
    #if not qapp:
    qapp = QtWidgets.QApplication(sys.argv) # this stucks QGIS main window
when the dialog's close button is pressed

    app = ApplicationWindow()
    app.show()
    app.activateWindow()
    app.raise_()
    qapp.exec()
    #app.exit()


When using "qapp = QtWidgets.QApplication.instance()", QGIS stucks
completely and no plot is shown ever.
When using "qapp = QtWidgets.QApplication(sys.argv)", the plot is shown and
updated correctly. But when pressing the "close button" of the plot window,
there are some strange effects (cannot start a plugin again) and the "close
button" of the QGIS main window is disabled. Have to shut down qgis-bin.exe
from the windows task-manager.
I am using:
QGIS Version 3.24.1 Tisler
matplotlib 3.5.1
Windows 10

Anybody have a solution for this problem?
Thanks a lot.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-user/attachments/20230214/3c235adb/attachment.htm>


More information about the QGIS-User mailing list