The original problem
On Ubuntu 22.04, I'm getting the following error with this MWE:
import matplotlib as mpl
from matplotlib import pyplot as plt
mpl.use("GTK4Agg")
The full traceback being
niko@niko-ubuntu:~/myproj$ python script.py
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gi/__init__.py", line 176, in require_foreign
_gi.require_foreign(namespace, symbol)
ModuleNotFoundError: No module named 'gi._gi_cairo'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/niko/.local/lib/python3.10/site-packages/matplotlib/backends/_backend_gtk.py", line 23, in <module>
gi.require_foreign("cairo")
File "/usr/lib/python3/dist-packages/gi/__init__.py", line 178, in require_foreign
raise ImportError(str(e))
ImportError: No module named 'gi._gi_cairo'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/niko/myproj/script.py", line 4, in <module>
mpl.use("GTK4Agg")
File "/home/niko/.local/lib/python3.10/site-packages/matplotlib/__init__.py", line 1233, in use
plt.switch_backend(name)
File "/home/niko/.local/lib/python3.10/site-packages/matplotlib/pyplot.py", line 271, in switch_backend
backend_mod = importlib.import_module(
File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/home/niko/.local/lib/python3.10/site-packages/matplotlib/backends/backend_gtk4agg.py", line 4, in <module>
from . import backend_agg, backend_gtk4
File "/home/niko/.local/lib/python3.10/site-packages/matplotlib/backends/backend_gtk4.py", line 26, in <module>
from . import _backend_gtk
File "/home/niko/.local/lib/python3.10/site-packages/matplotlib/backends/_backend_gtk.py", line 25, in <module>
raise ImportError("Gtk-based backends require cairo") from e
ImportError: Gtk-based backends require cairo
Checking cairo
By just reading to last line of the traceback, the first thing to do would be to try to install pycairo, which I tried, and got
niko@niko-ubuntu:~/myproj$ python -m pip install pycairo
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pycairo in /usr/lib/python3/dist-packages (1.20.1)
I can also verify that cairo is importable:
niko@niko-ubuntu:~/myproj$ ipython
>>> import cairo
>>> cairo.__file__
'/usr/lib/python3/dist-packages/cairo/__init__.py'
No module named 'gi._gi_cairo'
Then the next thing to do would be to read the full traceback, which I did, and realized that I should try to require_foreign("cairo"), which I did:
>>> import gi
>>> gi.require_foreign("cairo")
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
File /usr/lib/python3/dist-packages/gi/__init__.py:176, in require_foreign(namespace, symbol)
175 try:
--> 176 _gi.require_foreign(namespace, symbol)
177 except Exception as e:
ModuleNotFoundError: No module named 'gi._gi_cairo'
During handling of the above exception, another exception occurred:
ImportError Traceback (most recent call last)
Cell In[4], line 1
----> 1 gi.require_foreign("cairo")
File /usr/lib/python3/dist-packages/gi/__init__.py:178, in require_foreign(namespace, symbol)
176 _gi.require_foreign(namespace, symbol)
177 except Exception as e:
--> 178 raise ImportError(str(e))
179 importlib.import_module('gi.repository', namespace)
ImportError: No module named 'gi._gi_cairo'
Matplotlib docs & google
Googling for that exact phrase did not result to any search results, hence this question (to help future googles): What should I install in order to make matplotlib work with GTK4Agg backend? The matplotlib documentation says:
Question
Since I can import both gi and pycairo, one could assume they're both installed. Something is missing, as gi._gi_cairo is not there. Why is that so, and how to fix this?
Apparently, it is possible to install PyGObject, pycairo and cairo without installing the cairo bindings for the GObject library. These are included in the python3-gi-cairo package, and should be installed when PyGObject is installed, as mentioned in PyGObject documentation.
Therefore, the fix is to install the cairo bindings with