Skip to content

[Bug]: Qt, opencv, matplotlib interaction -> matplotlib figure, ax trigger error, causes SIGABRT without error trace. #29139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
BMaxV opened this issue Nov 14, 2024 · 2 comments

Comments

@BMaxV
Copy link

BMaxV commented Nov 14, 2024

Bug summary

Calling these functions after [bad setup]

fig = plt.figure(figsize=(20,20))
ax = fig.add_subplot(111)

causes a SIGABRT.

In short, the error / crash is fine and the steps to fix it for the user are clear / documented.

The problem is the non-graceful fail.

The issue isn't caused by matplotlib, but I'm reporting the issue here anyway, because I think matplotlib expects a certain setup, and triggers an error when that assumption isn't true. From my perspective, writing those simple lines should work or produce a pythonic error (assumptions not met, conflict with other package, whatever).

The fix for the underlying issue is to uninstall opencv-python and to install opencv-python-headless.

Code for reproduction

# not that simple.

Actual outcome

QObject::moveToThread: Current thread (0x25b0b60) is not the object's thread (0x3c70250).
Cannot move to target thread (0x25b0b60)

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/max/.local/lib/python3.12/site-packages/cv2/qt/plugins" 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: xcb, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx.

Expected outcome

a pythonic error trace that at least shows me which function caused the issue.

Additional information

There are multiple closed and a few open issues to essentially the topic here, on opencv and in various other packages that encounter the problem.

e.g. this one.

opencv/opencv-python#736

the search phrase

Could not load the Qt platform plugin "xcb" matplotlib

should turn up more examples.


I found this answer for how to handle report, but that doesn't really seem to work nicely. The error handler works in the sense it does detect the SIGABRT, but it still kills the process. Maybe, you can put this in...

https://discuss.python.org/t/how-can-i-handle-sigabrt-from-third-party-c-code-std-abort-call/22078/4

Their "solution" is to use multiprocessing, which is probably not something you want to build into your basic fig construction.


As a way to detect the problem I used what's being suggested in the python.org thread and sys.modules.

import sys
import ctypes
from signal import SIGABRT

c_globals = ctypes.CDLL(None) # POSIX

@ctypes.CFUNCTYPE(None, ctypes.c_int)
def sigabrt_handler(sig):
    print('SIGABRT handled!',sig)
    for x in sys.modules:
        if "cv2" in x:
            print("cv2 detected, this can cause a known issue [link]")
            break
        
    raise NotImplementedError("some interaction causes a C SIGABRT")

c_globals.signal(SIGABRT, sigabrt_handler)

which changes the error to look like this:

QObject::moveToThread: Current thread (0x331d4a0) is not the object's thread (0x4ab3630).
Cannot move to target thread (0x331d4a0)

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/max/.local/lib/python3.12/site-packages/cv2/qt/plugins" 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: xcb, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx.

SIGABRT handled! 6
modules
cv2 detected, this can cause a known issue [link]
Exception ignored on calling ctypes callback function: <function sigabrt_handler at 0x76fb050d8cc0>
Traceback (most recent call last):
  File "/home/max/Documents/Python/orometry-terrains/TerrainFromDivtree.py", line 40, in sigabrt_handler
    raise NotImplementedError("some interaction causes a C SIGABRT")
NotImplementedError: some interaction causes a C SIGABRT
fish: Job 2, 'python3 TerrainFromDivtree.py' terminated by signal SIGABRT (Abort)

still not good, but maybe if you plug the link in there, people can find better info on the problem than having to piece it together.

Anyway, thanks for your work on matplotlib!

If you're another user who encountered this bug, I hope this helps :)

Operating system

Ubuntu

Matplotlib Version

3.9.2

Matplotlib Backend

No response

Python version

3.12

Jupyter version

No response

Installation

pip

@tacaswell
Copy link
Member

tacaswell commented Nov 14, 2024

This a packaging problem specifically on the opencv side (per the issue you link) and generally with pip/wheel. Because wheels typically vendor all of their non-python dependencies you get things like this where two packages (pyqt and opencv) vendor incompatible versions of same same dependency (qt). See https://pypackaging-native.github.io for a lot more details

Your options are

  • install the opencv wheel that does not include a copy of Qt (as you note)
  • get lucky and find versions of pyqt and opencv that just happen to be built with the same version
  • use a packaging tool that is aware of all of the dependencies (e.g. system packages, homebrew, conda, ....). I strongly suggest looking at https://pixi.sh/latest/ which if you like the project-based environment.

I am going to close this because there is nothing we can do on the Matplotib side to solve this problem as it is a poor interaction between the wheels two other packages and it needs to be fixed either between those packages or by PyPA at a systematic level. The problem can be avoided by using more complete packaging ecosystems. Sorry I don't have a better answer.

@tacaswell tacaswell closed this as not planned Won't fix, can't repro, duplicate, stale Nov 14, 2024
@BMaxV
Copy link
Author

BMaxV commented Nov 14, 2024

Thanks for the additional info!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants