2025, Oct 22 08:03
Как исправить ошибку No module named matplotlib при сборке PyInstaller с PyQt6
Почему PyInstaller не включает matplotlib: ошибка No module named matplotlib при сборке .exe для PyQt6 на Windows и как решить её установкой зависимости.
Упаковка небольшого настольного приложения на PyQt6 в один исполняемый файл для Windows нередко спотыкается о на удивление простую проблему: отсутствующую зависимость на этапе сборки. Даже если прописать скрытые импорты и флаги collect-all, PyInstaller не сможет включить библиотеки, которых нет в текущем окружении. Итог — ошибка при запуске с понятным сообщением: No module named matplotlib.
Как воспроизвести окружение и сбой сборки
Приложение собирается в единый .exe с PyInstaller и следующими зависимостями:
PyQt6==6.9.1
PyQt6-Qt6==6.9.1
PyQt6_sip==13.10.2
qt-material==2.17
pyinstaller==6.14.2
В файле spec для PyInstaller добавлены скрытые импорты для matplotlib и его бэкендов:
# -*- mode: python ; coding: utf-8 -*-
graph = Analysis(
['DSS.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=['matplotlib', 'matplotlib.backends.backend_tkagg', 'matplotlib.backends.backend_pdf'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=['PyQt5'],
noarchive=False,
optimize=0,
)
archive = PYZ(graph.pure)
app_exe = EXE(
archive,
graph.scripts,
graph.binaries,
graph.datas,
[],
name='DNA_Sequence_Similarities',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['icon.ico'],
)
bundle_collect = COLLECT(
app_exe,
graph.binaries,
graph.zipfiles,
graph.datas,
strip=False,
upx=True,
upx_exclude=[],
name='DNA_Sequence_Similarities',
)
Команда сборки дополнительно указывает скрытые импорты и пытается собрать пакеты:
pyinstaller DSS.py
--name DNA_Sequence_Similarities
--onefile
--windowed
--icon=icon.ico
--hidden-import=matplotlib
--hidden-import=matplotlib.backends.backend_tkagg
--hidden-import=matplotlib.backends.backend_pdf
--collect-all matplotlib
--collect-all qt_material
--collect-all PyQt6
Несмотря на это, исполняемый файл на целевых машинах падает с No module named matplotlib. Лог сборки подтверждает проблему: Hidden import 'matplotlib.backends.backend_tkagg' not found и Hidden import 'matplotlib.backends.backend_pdf' not found.
В чём реальная причина
PyInstaller анализирует текущее окружение Python и «замораживает» только те импорты, которые удаётся разрешить. Если библиотека не установлена на момент сборки, включать попросту нечего. В показанной конфигурации matplotlib отсутствует в списке зависимостей и, следовательно, не установлен в окружении сборки. Поэтому флаги hidden-import не срабатывают: PyInstaller не может найти модули, которых локально нет.
Во время выполнения сообщение максимально прямое, а на этапе анализа повторяется то же самое: скрытые импорты бэкендов matplotlib обнаружить не удаётся.
Решение
Установите matplotlib в окружение сборки и добавьте его в зависимости проекта. Как только библиотека появится, текущий spec и настройки hidden-import позволят PyInstaller найти и упаковать её вместе с исполняемым файлом.
pip install matplotlib
В итоге набор зависимостей будет таким:
PyQt6==6.9.1
PyQt6-Qt6==6.9.1
PyQt6_sip==13.10.2
qt-material==2.17
pyinstaller==6.14.2
matplotlib
Пересоберите приложение той же командой — в исполняемый файл попадёт matplotlib. Предыдущие ошибки лога о недостающих бэкендах matplotlib исчезнут, как только пакет будет доступен.
Почему это важно
При поставке автономного десктопного приложения любой импорт, выполняемый во время работы, должен присутствовать в окружении уже на этапе сборки. Иначе PyInstaller не сможет его «заморозить», и финальный бинарник упадёт на машинах без установленной зависимости. Это особенно критично для GUI-стеков вроде PyQt6, которые часто интегрируются с библиотеками визуализации. Сборка должна быть самодостаточной, а начинается это с полного списка зависимостей.
Стоит прислушиваться и к сообщениям, которые выдаёт сборка. Например, в логе отмечено, что qt_material следует импортировать после PySide или PyQt. Подобные подсказки помогают заранее проверить порядок импортов и ожидания упаковки ещё до распространения.
Выводы
Держите окружение сборки в соответствии с реальными импортами приложения, убедитесь, что все нужные библиотеки перечислены и установлены — дальше PyInstaller справится сам. Если в логе появляется сообщение, что скрытый импорт не найден, самый прямой путь к решению — сделать модуль доступным в окружении, как показано на примере с matplotlib.