matplotlib.backends.backend_qtagg, matplotlib.backends.backend_qtcairo#

NOTE These Backends are not (auto) documented here, to avoid adding a dependency to building the docs.

Qt Bindings#

There are currently 2 actively supported Qt versions, Qt5 and Qt6, and two supported Python bindings per version -- PyQt5 and PySide2 for Qt5 and PyQt6 and PySide6 for Qt6 [1]. Matplotlib's qtagg and qtcairo backends (matplotlib.backends.backend_qtagg and matplotlib.backend.backend_qtcairo) support all these bindings, with common parts factored out in the matplotlib.backends.backend_qt module.

At runtime, these backends select the actual binding used as follows:

  1. If a binding's QtCore subpackage is already imported, that binding is selected (the order for the check is PyQt6, PySide6, PyQt5, PySide2).

  2. If the QT_API environment variable is set to one of "PyQt6", "PySide6", "PyQt5", "PySide2" (case-insensitive), that binding is selected. (See also the documentation on Environment variables.)

  3. Otherwise, the first available backend in the order PyQt6, PySide6, PyQt5, PySide2 is selected.

In the past, Matplotlib used to have separate backends for each version of Qt (e.g. qt4agg/matplotlib.backends.backend_qt4agg and qt5agg/matplotlib.backends.backend_qt5agg). This scheme was dropped when support for Qt6 was added. For back-compatibility, qt5agg/backend_qt5agg and qt5cairo/backend_qt5cairo remain available; selecting one of these backends forces the use of a Qt5 binding. Their use is discouraged and backend_qtagg or backend_qtcairo should be preferred instead. However, these modules will not be deprecated until we drop support for Qt5.

While both PyQt and Qt for Python (aka PySide) closely mirror the underlying C++ API they are wrapping, they are not drop-in replacements for each other [2]. To account for this, Matplotlib has an internal API compatibility layer in matplotlib.backends.qt_compat which covers our needs. Despite being a public module, we do not consider this to be a stable user-facing API and it may change without warning [3].