I am trying to show a matplotlib.pyplot figure on Python 3.10 but can't. I am aware of this question and tried their answers but is still unsuccessful. The default OS distribution is Ubuntu 24.04 using Python 3.12 as a default.
Here is how I setup the Python 3.10 project venv
and installed numpy
and matplotlib
:
$ uv init test_py310 --python 3.10
Initialized project `test-py310` at `/home/user/test_py310`
$ cd test_py310/
$ uv add numpy matplotlib
Using CPython 3.10.16
Creating virtual environment at: .venv
Resolved 12 packages in 136ms
Prepared 1 package in 1.96s
Installed 11 packages in 43ms
+ contourpy==1.3.2
+ cycler==0.12.1
+ fonttools==4.57.0
+ kiwisolver==1.4.8
+ matplotlib==3.10.1
+ numpy==2.2.5
+ packaging==25.0
+ pillow==11.2.1
+ pyparsing==3.2.3
+ python-dateutil==2.9.0.post0
+ six==1.17.0
test_matplotlib.py:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y, label='sin(x)', color='blue', linestyle='--')
plt.show()
Error:
/home/user/Coding/test_py310/.venv/bin/python /home/user/test_py310/test_matplotlib,py
/home/user/test_py310/test_matplotlib,py:7: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown
plt.show()
Next, I tried installing PyQt5
as shared by this answer but still encountered error.
$ uv add pyqt5
Resolved 15 packages in 89ms
Installed 3 packages in 45ms
+ pyqt5==5.15.11
+ pyqt5-qt5==5.15.16
+ pyqt5-sip==12.17.0
Running the same python script
$ /home/user/test_py310/.venv/bin/python /home/user/test_py310/test_matplotlib,py
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.
Aborted (core dumped)
Changing import matplotlib.pyplot as plt
to:
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
Gave this error:
$ /home/user/test_py310/.venv/bin/python /home/user/test_py310/test_matplotlib,py
AttributeError: module '_tkinter' has no attribute '__file__'. Did you mean: '__name__'?
The above exception was the direct cause of the following exception:
ImportError: failed to load tkinter functions
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/user/test_py310/test_matplotlib,py", line 9, in <module>
plt.plot(x, y, label='sin(x)', color='blue', linestyle='--')
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/pyplot.py", line 3827, in plot
return gca().plot(
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/pyplot.py", line 2774, in gca
return gcf().gca()
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/pyplot.py", line 1108, in gcf
return figure()
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/pyplot.py", line 1042, in figure
manager = new_figure_manager(
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/pyplot.py", line 551, in new_figure_manager
_warn_if_gui_out_of_main_thread()
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/pyplot.py", line 528, in _warn_if_gui_out_of_main_thread
canvas_class = cast(type[FigureCanvasBase], _get_backend_mod().FigureCanvas)
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/pyplot.py", line 369, in _get_backend_mod
switch_backend(rcParams._get("backend"))
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/pyplot.py", line 425, in switch_backend
module = backend_registry.load_backend_module(newbackend)
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/backends/registry.py", line 317, in load_backend_module
return importlib.import_module(module_name)
File "/home/user/.local/share/uv/python/cpython-3.10.16-linux-x86_64-gnu/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/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/backends/backend_tkagg.py", line 1, in <module>
from . import _backend_tk
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/backends/_backend_tk.py", line 25, in <module>
from . import _tkagg
ImportError: initialization failed
Using
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
gave
$ /home/user/test_py310/.venv/bin/python /home/user/test_py310/test_matplotlib,py
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.
Aborted (core dumped)
I have also removed pyqt5 and added pyqt6, and used matplotlib.use('Qt6Agg')
but got this error:
$ /home/user/test_py310/.venv/bin/python /home/user/test_py310/test_matplotlib,py
Traceback (most recent call last):
File "/home/user/test_py310/test_matplotlib,py", line 4, in <module>
matplotlib.use('Qt6Agg')
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/__init__.py", line 1265, in use
name = rcsetup.validate_backend(backend)
File "/home/user/test_py310/.venv/lib/python3.10/site-packages/matplotlib/rcsetup.py", line 278, in validate_backend
raise ValueError(msg)
ValueError: 'Qt6Agg' is not a valid value for backend; supported values are ['gtk3agg', 'gtk3cairo', 'gtk4agg', 'gtk4cairo', 'macosx', 'nbagg', 'notebook', 'qtagg', 'qtcairo', 'qt5agg', 'qt5cairo', 'tkagg', 'tkcairo', 'webagg', 'wx', 'wxagg', 'wxcairo', 'agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg', 'template']
What must I do to be able to plot a matplotlib.pyplot figure in a virtual environment that is installed with Python 3.10? Just to add, I am able show a matplotlib.pyplot figure in a separate virtual environment using Python 3.12.
I uses Linux Mint 22 based on Ubuntu 24.04.
Code works for me with uv
and Python 3.10
when I install PyQt6
but not with PyQt5
And it doesn't need line matplotlib.use('Qt5Agg')
nor matplotlib.use('QtAgg')
(but it works also with those lines)
As for tkinter
: normally tkinter
is intalled directly with Python
but on Ubuntu it is separated package which is installed with apt install python3.10-tk
.
And I think this can be problem to install it in version installed with uv
.
BTW: on version Ubuntu Server
(which doesn't have installed X11, and usually is used on computers without monitor) it may have Python without tkinter
because tkinter
is useless without X11
and monitor.
There is no problem when you install full Python 3.10
using apt install python3.10-full
or apt install python3.10 python3.10-tk
and later create virtual environment with python3.10 -m venv ...
Full code used for tests:
$ uv init test_py310 --python 3.10
$ cd test_py310/
$ uv add numpy matplotlib pyqt6
$ uv run main.py
main.py
It allows to run with parameter like uv run main.py tkagg
import sys
print('>>> Executable:', sys.executable)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
# matplotlib.use('QtAgg') # works for me when installed `PyQt6` but not `PyQt5`
# matplotlib.use('Qt5Agg') # works for me when installed `PyQt6` but not `PyQt5`
# matplotlib.use('Qt6Agg') # doesn't exist `Qt6Agg`
# matplotlib.use('TkAgg') # `tkinter` is not installed with `uv`
if len(sys.argv) > 1:
print('>>> Using:', sys.argv[1])
matplotlib.use(sys.argv[1])
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y, label='sin(x)', color='blue', linestyle='--')
# plt.ion() # ion = Interactive ON
plt.show()
These setup commands worked for Ubuntu 24.04 (tested by @SunBear):
$ uv init test_py310 --python 3.10
$ cd test_py310/
$ uv add numpy matplotlib pyqt6
$ sudo apt install python3.10-tk libxcb-cursor0
$ uv run main.py