Pycairo
Pycairo is a Python module providing bindings for the cairo graphics library. It enables Python programs to create high-quality vector graphics that scale without loss of clarity and can be output in various formats like PNG, SVG, PDF, and PostScript. The library is actively maintained with regular releases, typically multiple per year, following semantic versioning since v1.11.0. It currently supports Python 3.10+ and PyPy3.
Warnings
- breaking Pycairo v1.29.0 drops support for Python 3.9 and PyPy 3.10. Ensure your Python environment is 3.10 or newer.
- breaking In Pycairo v1.28.0, the `Path.__iter__()` method now returns a `PathDataType` (an integer subtype) instead of a raw `int`. Code relying on the exact type returned should be updated.
- deprecated Calling `ImageSurface.get_data()` on an already 'finished' surface now emits a `DeprecationWarning` in v1.28.0. In a future version, this will raise an exception.
- gotcha Installing Pycairo often fails if the underlying C `cairo` graphics library and its development headers (e.g., `libcairo2-dev`) and `pkg-config` are not already present on the system. `pip install pycairo` alone is usually insufficient.
- gotcha Cairo `Context` objects (and their paths, fills) are not persistent across drawing operations, especially for GUI surfaces. Drawings must be regenerated in their entirety during expose or redraw events, rather than relying on previous states.
- gotcha If the system's `cairo` C library version changes, or if `pycairo` was built against a different `cairo` version than is currently active, `pip` might use a cached wheel that causes runtime errors. This can manifest as unexpected `ImportError` or other C-level linking issues.
Install
-
pip install pycairo -
sudo apt install libcairo2-dev pkg-config python3-dev -
brew install cairo pkg-config -
sudo dnf install cairo-devel pkg-config python3-devel -
pip install --force-reinstall --no-cache-dir pycairo
Imports
- cairo
import cairo
Quickstart
import cairo
import math
WIDTH, HEIGHT = 256, 256
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cairo.Context(surface)
ctx.scale(WIDTH, HEIGHT)
ctx.set_line_width(0.04)
# Draw a curve
x, y, x1, y1 = 0.1, 0.5, 0.4, 0.9
x2, y2, x3, y3 = 0.6, 0.1, 0.9, 0.5
ctx.move_to(x, y)
ctx.curve_to(x1, y1, x2, y2, x3, y3)
ctx.stroke()
# Draw guide lines
ctx.set_source_rgba(1, 0.2, 0.2, 0.6) # Red with transparency
ctx.set_line_width(0.02)
ctx.move_to(x, y)
ctx.line_to(x1, y1)
ctx.move_to(x2, y2)
ctx.line_to(x3, y3)
ctx.stroke()
surface.write_to_png("example.png")
print("Generated example.png")