Skip to content
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

Mac M3 Python can't find Cairo #1090

Open
hathawayj opened this issue Apr 28, 2024 · 3 comments
Open

Mac M3 Python can't find Cairo #1090

hathawayj opened this issue Apr 28, 2024 · 3 comments

Comments

@hathawayj
Copy link

ggsave(chart, "anychart.png")

results in

{
	"name": "OSError",
	"message": "no library called \"cairo-2\" was found\nno library called \"cairo\" was found\nno library called \"libcairo-2\" was found\ncannot load library 'libcairo.so.2': dlopen(libcairo.so.2, 0x0002): tried: 'libcairo.so.2' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibcairo.so.2' (no such file), '/usr/lib/libcairo.so.2' (no such file, not in dyld cache), 'libcairo.so.2' (no such file), '/usr/lib/libcairo.so.2' (no such file, not in dyld cache).  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo.so.2'\ncannot load library 'libcairo.2.dylib': dlopen(libcairo.2.dylib, 0x0002): tried: 'libcairo.2.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibcairo.2.dylib' (no such file), '/usr/lib/libcairo.2.dylib' (no such file, not in dyld cache), 'libcairo.2.dylib' (no such file), '/usr/lib/libcairo.2.dylib' (no such file, not in dyld cache).  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo.2.dylib'\ncannot load library 'libcairo-2.dll': dlopen(libcairo-2.dll, 0x0002): tried: 'libcairo-2.dll' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibcairo-2.dll' (no such file), '/usr/lib/libcairo-2.dll' (no such file, not in dyld cache), 'libcairo-2.dll' (no such file), '/usr/lib/libcairo-2.dll' (no such file, not in dyld cache).  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo-2.dll'",
	"stack": "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mOSError\u001b[0m                                   Traceback (most recent call last)\nFile \u001b[1;32m/Users/hathawayj/git/ki-analysis/Rally_87_QA/A-cerner/encounters_explore.py:2\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[39m# %%\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m ggsave(encounters_by_year,\u001b[39m\"\u001b[39;49m\u001b[39mcharts/encounters_by_year.png\u001b[39;49m\u001b[39m\"\u001b[39;49m)\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/lets_plot/export/ggsave_.py:109\u001b[0m, in \u001b[0;36mggsave\u001b[0;34m(plot, filename, path, iframe, scale, w, h, unit, dpi)\u001b[0m\n\u001b[1;32m    107\u001b[0m     \u001b[39mreturn\u001b[39;00m _to_html(plot, pathname, iframe\u001b[39m=\u001b[39miframe)\n\u001b[1;32m    108\u001b[0m \u001b[39melif\u001b[39;00m ext \u001b[39min\u001b[39;00m [\u001b[39m'\u001b[39m\u001b[39mpng\u001b[39m\u001b[39m'\u001b[39m, \u001b[39m'\u001b[39m\u001b[39mpdf\u001b[39m\u001b[39m'\u001b[39m]:\n\u001b[0;32m--> 109\u001b[0m     \u001b[39mreturn\u001b[39;00m _export_as_raster(plot, pathname, scale, export_format\u001b[39m=\u001b[39;49mext, w\u001b[39m=\u001b[39;49mw, h\u001b[39m=\u001b[39;49mh, unit\u001b[39m=\u001b[39;49munit, dpi\u001b[39m=\u001b[39;49mdpi)\n\u001b[1;32m    110\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m    111\u001b[0m     \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\n\u001b[1;32m    112\u001b[0m         \u001b[39m\"\u001b[39m\u001b[39mUnsupported file extension: \u001b[39m\u001b[39m'\u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39mPlease use one of: \u001b[39m\u001b[39m'\u001b[39m\u001b[39mpng\u001b[39m\u001b[39m'\u001b[39m\u001b[39m, \u001b[39m\u001b[39m'\u001b[39m\u001b[39msvg\u001b[39m\u001b[39m'\u001b[39m\u001b[39m, \u001b[39m\u001b[39m'\u001b[39m\u001b[39mpdf\u001b[39m\u001b[39m'\u001b[39m\u001b[39m, \u001b[39m\u001b[39m'\u001b[39m\u001b[39mhtml\u001b[39m\u001b[39m'\u001b[39m\u001b[39m, \u001b[39m\u001b[39m'\u001b[39m\u001b[39mhtm\u001b[39m\u001b[39m'\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mformat(ext)\n\u001b[1;32m    113\u001b[0m     )\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/lets_plot/plot/core.py:882\u001b[0m, in \u001b[0;36m_export_as_raster\u001b[0;34m(spec, path, scale, export_format, w, h, unit, dpi)\u001b[0m\n\u001b[1;32m    879\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_export_as_raster\u001b[39m(spec, path, scale: \u001b[39mfloat\u001b[39m, export_format: \u001b[39mstr\u001b[39m, w\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, h\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, unit\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, dpi\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m Union[\n\u001b[1;32m    880\u001b[0m     \u001b[39mstr\u001b[39m, \u001b[39mNone\u001b[39;00m]:\n\u001b[1;32m    881\u001b[0m     \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m--> 882\u001b[0m         \u001b[39mimport\u001b[39;00m \u001b[39mcairosvg\u001b[39;00m\n\u001b[1;32m    883\u001b[0m     \u001b[39mexcept\u001b[39;00m \u001b[39mImportError\u001b[39;00m:\n\u001b[1;32m    884\u001b[0m         \u001b[39mimport\u001b[39;00m \u001b[39msys\u001b[39;00m\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/cairosvg/__init__.py:26\u001b[0m\n\u001b[1;32m     22\u001b[0m VERSION \u001b[39m=\u001b[39m __version__ \u001b[39m=\u001b[39m (ROOT \u001b[39m/\u001b[39m \u001b[39m'\u001b[39m\u001b[39mVERSION\u001b[39m\u001b[39m'\u001b[39m)\u001b[39m.\u001b[39mread_text()\u001b[39m.\u001b[39mstrip()\n\u001b[1;32m     25\u001b[0m \u001b[39m# VERSION is used in the \"url\" module imported by \"surface\"\u001b[39;00m\n\u001b[0;32m---> 26\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39m.\u001b[39;00m \u001b[39mimport\u001b[39;00m surface  \u001b[39m# noqa isort:skip\u001b[39;00m\n\u001b[1;32m     29\u001b[0m SURFACES \u001b[39m=\u001b[39m {\n\u001b[1;32m     30\u001b[0m     \u001b[39m'\u001b[39m\u001b[39mPDF\u001b[39m\u001b[39m'\u001b[39m: surface\u001b[39m.\u001b[39mPDFSurface,\n\u001b[1;32m     31\u001b[0m     \u001b[39m'\u001b[39m\u001b[39mPNG\u001b[39m\u001b[39m'\u001b[39m: surface\u001b[39m.\u001b[39mPNGSurface,\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m     34\u001b[0m     \u001b[39m'\u001b[39m\u001b[39mSVG\u001b[39m\u001b[39m'\u001b[39m: surface\u001b[39m.\u001b[39mSVGSurface,\n\u001b[1;32m     35\u001b[0m }\n\u001b[1;32m     38\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39msvg2svg\u001b[39m(bytestring\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, \u001b[39m*\u001b[39m, file_obj\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, url\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, dpi\u001b[39m=\u001b[39m\u001b[39m96\u001b[39m,\n\u001b[1;32m     39\u001b[0m             parent_width\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, parent_height\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, scale\u001b[39m=\u001b[39m\u001b[39m1\u001b[39m, unsafe\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m,\n\u001b[1;32m     40\u001b[0m             background_color\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, negate_colors\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m, invert_images\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m,\n\u001b[1;32m     41\u001b[0m             write_to\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, output_width\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, output_height\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m):\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/cairosvg/surface.py:9\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[39mimport\u001b[39;00m \u001b[39mcopy\u001b[39;00m\n\u001b[1;32m      7\u001b[0m \u001b[39mimport\u001b[39;00m \u001b[39mio\u001b[39;00m\n\u001b[0;32m----> 9\u001b[0m \u001b[39mimport\u001b[39;00m \u001b[39mcairocffi\u001b[39;00m \u001b[39mas\u001b[39;00m \u001b[39mcairo\u001b[39;00m\n\u001b[1;32m     11\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39m.\u001b[39;00m\u001b[39mcolors\u001b[39;00m \u001b[39mimport\u001b[39;00m color, negate_color\n\u001b[1;32m     12\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39m.\u001b[39;00m\u001b[39mdefs\u001b[39;00m \u001b[39mimport\u001b[39;00m (\n\u001b[1;32m     13\u001b[0m     apply_filter_after_painting, apply_filter_before_painting, clip_path,\n\u001b[1;32m     14\u001b[0m     filter_, gradient_or_pattern, linear_gradient, marker, mask, paint_mask,\n\u001b[1;32m     15\u001b[0m     parse_all_defs, pattern, prepare_filter, radial_gradient, use)\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/cairocffi/__init__.py:60\u001b[0m\n\u001b[1;32m     55\u001b[0m     error_message \u001b[39m=\u001b[39m \u001b[39m'\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m.\u001b[39mjoin(  \u001b[39m# pragma: no cover\u001b[39;00m\n\u001b[1;32m     56\u001b[0m         \u001b[39mstr\u001b[39m(exception) \u001b[39mfor\u001b[39;00m exception \u001b[39min\u001b[39;00m exceptions)\n\u001b[1;32m     57\u001b[0m     \u001b[39mraise\u001b[39;00m \u001b[39mOSError\u001b[39;00m(error_message)  \u001b[39m# pragma: no cover\u001b[39;00m\n\u001b[0;32m---> 60\u001b[0m cairo \u001b[39m=\u001b[39m dlopen(\n\u001b[1;32m     61\u001b[0m     ffi, (\u001b[39m'\u001b[39;49m\u001b[39mcairo-2\u001b[39;49m\u001b[39m'\u001b[39;49m, \u001b[39m'\u001b[39;49m\u001b[39mcairo\u001b[39;49m\u001b[39m'\u001b[39;49m, \u001b[39m'\u001b[39;49m\u001b[39mlibcairo-2\u001b[39;49m\u001b[39m'\u001b[39;49m),\n\u001b[1;32m     62\u001b[0m     (\u001b[39m'\u001b[39;49m\u001b[39mlibcairo.so.2\u001b[39;49m\u001b[39m'\u001b[39;49m, \u001b[39m'\u001b[39;49m\u001b[39mlibcairo.2.dylib\u001b[39;49m\u001b[39m'\u001b[39;49m, \u001b[39m'\u001b[39;49m\u001b[39mlibcairo-2.dll\u001b[39;49m\u001b[39m'\u001b[39;49m))\n\u001b[1;32m     65\u001b[0m \u001b[39mclass\u001b[39;00m \u001b[39m_keepref\u001b[39;00m(\u001b[39mobject\u001b[39m):  \u001b[39m# noqa: N801\u001b[39;00m\n\u001b[1;32m     66\u001b[0m \u001b[39m    \u001b[39m\u001b[39m\"\"\"Function wrapper that keeps a reference to another object.\"\"\"\u001b[39;00m\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/cairocffi/__init__.py:57\u001b[0m, in \u001b[0;36mdlopen\u001b[0;34m(ffi, library_names, filenames)\u001b[0m\n\u001b[1;32m     53\u001b[0m         exceptions\u001b[39m.\u001b[39mappend(exception)\n\u001b[1;32m     55\u001b[0m error_message \u001b[39m=\u001b[39m \u001b[39m'\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m.\u001b[39mjoin(  \u001b[39m# pragma: no cover\u001b[39;00m\n\u001b[1;32m     56\u001b[0m     \u001b[39mstr\u001b[39m(exception) \u001b[39mfor\u001b[39;00m exception \u001b[39min\u001b[39;00m exceptions)\n\u001b[0;32m---> 57\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mOSError\u001b[39;00m(error_message)\n\n\u001b[0;31mOSError\u001b[0m: no library called \"cairo-2\" was found\nno library called \"cairo\" was found\nno library called \"libcairo-2\" was found\ncannot load library 'libcairo.so.2': dlopen(libcairo.so.2, 0x0002): tried: 'libcairo.so.2' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibcairo.so.2' (no such file), '/usr/lib/libcairo.so.2' (no such file, not in dyld cache), 'libcairo.so.2' (no such file), '/usr/lib/libcairo.so.2' (no such file, not in dyld cache).  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo.so.2'\ncannot load library 'libcairo.2.dylib': dlopen(libcairo.2.dylib, 0x0002): tried: 'libcairo.2.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibcairo.2.dylib' (no such file), '/usr/lib/libcairo.2.dylib' (no such file, not in dyld cache), 'libcairo.2.dylib' (no such file), '/usr/lib/libcairo.2.dylib' (no such file, not in dyld cache).  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo.2.dylib'\ncannot load library 'libcairo-2.dll': dlopen(libcairo-2.dll, 0x0002): tried: 'libcairo-2.dll' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibcairo-2.dll' (no such file), '/usr/lib/libcairo-2.dll' (no such file, not in dyld cache), 'libcairo-2.dll' (no such file), '/usr/lib/libcairo-2.dll' (no such file, not in dyld cache).  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo-2.dll'"
}

Trying this command seems to show that Python doesn't see Cairo because I have the files in those locations.

 curl "https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/includes/debug/cairo-lookup-macos.py" | python3 -

I tried BREW install and conda install and neither worked

I think it is an M3 issue but I can't quite figure it out. I would love help.

@hathawayj
Copy link
Author

Screenshot 2024-04-28 at 5 56 09 PM

@alshan
Copy link
Collaborator

alshan commented Apr 29, 2024

Hi, try pip3 install cairosvg.
See "Install" section in cairoSVG docs.

@IKupriyanov-HORIS
Copy link
Collaborator

IKupriyanov-HORIS commented May 2, 2024

Hi! There is a CairoSVG issue with the workaround. Hopefully, this information may help.

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

3 participants