Skip to content

Repository files navigation

[logo]

Gizeh — Cairo for tourists

Gizeh is a Python library for vector graphics, built on top of cairocffi (Cairo bindings for Python). Cairo is powerful but low-level; Gizeh adds a small set of intuitive primitives to make drawing easier.

# Let's draw a red circle!
import gizeh

surface = gizeh.Surface(width=320, height=260)  # pixels
circle = gizeh.circle(r=30, xy=[40, 40], fill=(1, 0, 0))
circle.draw(surface)  # draw the circle on the surface
surface.write_to_png("circle.png")  # export as PNG

See Gizeh in action (combined with MoviePy for animations) in this blog post.

Gizeh supports Python 3.7+.

Installation

Gizeh requires the Cairo graphics library to be installed on your system.

  • macOS (Homebrew):
    • brew install cairo pkg-config
  • Debian/Ubuntu:
    • sudo apt-get install -y libcairo2-dev pkg-config

Then install the Python package:

pip install gizeh

Alternatively, from source (editable/development install):

pip install -e .

User Guide

This guide, along with the examples in gizeh/examples, should give you everything you need to get started. Check docstrings for details.

Surfaces

A Surface is a rectangle of fixed dimensions (in pixels) on which you draw elements, and which you can save/export as an image:

import gizeh

# initialize surface
surface = gizeh.Surface(width=320, height=260)  # in pixels

# make a shape and draw it on the surface
circle = gizeh.circle(r=30, xy=[40, 40], fill=(1, 1, 1))
circle.draw(surface)

# export the surface
surface.get_npimage()           # returns a (width x height x 3) numpy array
surface.write_to_png("circle.png")

Elements

Basic elements are circles, rectangles, lines, text, etc., that you draw on a surface using my_element.draw(surface). Common parameters:

  • xy: center coordinates of the object. At render time (surface.write_to_png) you can set y_origin to "top" (default) or "bottom". With "top", (0, 0) is the upper-left of the final image; the bottom-right is (width, height). With "bottom", (0, 0) is the bottom-left (like plots), and (width, height) is the top-right.
  • angle: rotation (radians) around xy.
  • fill: interior fill (default: none). Can be a color (R, G, B), gradient, image pattern, etc.
  • stroke: contour fill; same rules as fill.
  • stroke_width: contour width (pixels). Default is 0 (no stroke).

Examples:

import numpy as np
Pi = np.pi

circ = gizeh.circle(r=30, xy=(50, 50), fill=(1, 1, 1))
rect = gizeh.rectangle(lx=60.3, ly=45, xy=(60, 70), fill=(0, 1, 0), angle=Pi/8)
sqr  = gizeh.square(l=20, stroke=(1, 1, 1), stroke_width=1.5)
arc  = gizeh.arc(r=20, a1=Pi/4, a2=3*Pi/4, fill=(1, 1, 1))
text = gizeh.text("Hello world", fontfamily="Impact", fontsize=40,
                  fill=(1, 1, 1), xy=(100, 100), angle=Pi/12)
poly = gizeh.regular_polygon(r=40, n=5, angle=np.pi/4, xy=[40, 50], fill=(1, 0, 1))
line = gizeh.polyline(points=[(0, 0), (20, 30), (40, 40), (0, 10)],
                      stroke_width=3, stroke=(1, 0, 0), fill=(0, 1, 0))

Fill and stroke

fill and stroke can be:

  • RGB (r, g, b) with values in [0, 1]
  • RGBA (r, g, b, a) with a in [0, 1]
  • gizeh.ColorGradient
  • gizeh.ImagePattern (an image)
  • A NumPy RGB/RGBA image array (where implemented)

Transformations

Elements can be transformed (translated, rotated, scaled). All transformations are out-of-place: they return a modified copy.

square_1 = gizeh.square(l=20, xy=[30, 35], fill=(1, 0, 0))
square_2 = square_1.rotate(np.pi/8)                    # rotation around [0, 0] by default
square_3 = square_2.rotate(np.pi/4, center=[10, 15])   # rotation around a center
square_4 = square_1.scale(2)                           # two times bigger
square_5 = square_1.scale(sx=2, sy=3)                  # width x2, height x3
square_6 = square_1.scale(2, center=[30, 30])          # zoom around a center
square_7 = square_1.translate(xy=[5, 15])              # translation

Groups

A Group is a collection of elements (including nested groups) transformed and drawn together:

square = gizeh.square(l=20, fill=(1, 0, 0), xy=(40, 40))
circle = gizeh.circle(r=20, fill=(1, 1, 0), xy=(50, 30))
group_1 = gizeh.Group([square, circle])
group_2 = group_1.translate(xy=[30, 30]).rotate(np.pi/4)
group_3 = gizeh.Group([circle, group_1])

surface = gizeh.Surface(width=300, height=200)
group_1.draw(surface)
group_2.draw(surface)
group_3.draw(surface)
surface.write_to_png("my_masterwork.png")

Troubleshooting installation

If pip installation fails, ensure you have the system Cairo development packages and pkg-config installed (see “Installation” above).

  • macOS (Homebrew): brew install cairo pkg-config
  • Debian/Ubuntu: sudo apt-get install -y libcairo2-dev pkg-config

Developers

Development uses uv for fast Python packaging and workflows.

Prerequisites:

  • Install system packages
    • macOS: brew install uv cairo pkg-config
    • Debian/Ubuntu: sudo apt-get install -y libcairo2-dev pkg-config and install uv from its docs

Setup and install deps:

uv python install 3.12
uv venv --python 3.12
uv sync --group dev

Run tests:

uv run pytest -q

Run a specific test:

uv run pytest -q tests/test_samples.py::test_random_squares

Quick import check:

uv run python -c "import gizeh, numpy, cairocffi; print('ok')"

Install and run pre-commit hooks:

uv run pre-commit install
uv run pre-commit run --all-files

Contributing

Gizeh is open-source (MIT) by Zulko. Contributions are welcome—issues and pull requests on GitHub.

About

Simple Vector Graphics for Python

Resources

Stars

721 stars

Watchers

18 watching

Forks

Releases

Packages

Used by

Contributors

Languages