pygraphics

August 12, 2026 · View on GitHub

Native and pure-Python pygraphics for MicroPython, CircuitPython, and CPython. The C module can be built into MicroPython or CircuitPython, while the pure-Python package is available for users who prefer not to compile their own build. Import as pygraphics.

ProductPip / MIPRole
pygraphicsTestPyPI pydevices-pygraphicsNative/C-extension wheel for CPython and for embedded builds that include the module (prefer on desktop/Android/Pyodide when available)
pygraphicsMIP pygraphicsPure-Python package for users who do not want to compile their own build (same public API)

One release tag vX.Y.Z publishes both products at that version.

Install

Native (TestPyPI)

pip install \
  -i https://test.pypi.org/simple/ \
  --extra-index-url https://pypi.org/simple/ \
  pydevices-pygraphics

Pure Python (MIP)

import mip
mip.install("pygraphics", index="https://PyDevices.github.io/micropython-lib/mip/PyDevices")

MicroPython (MIP)

import mip
mip.install("pygraphics", index="https://PyDevices.github.io/micropython-lib/mip/PyDevices")

Quick start

import pygraphics
from pygraphics import FrameBuffer, RGB565

fb = FrameBuffer(bytearray(160 * 128 * 2), 160, 128, RGB565)
fb.fill(0)
fb.fill_rect(10, 10, 40, 40, 0xF800)
print(pygraphics.implementation())  # native_cmod or pygraphics_python

What you get

  • Area — rectangle geometry helper
  • FrameBuffer — framebuf-compatible drawing surface (returns Area bounds)
  • Format constants: MONO_VLSB, MONO_HLSB, MONO_HMSB, RGB565, GS2_HMSB, GS4_HMSB, GS8, RGB888
  • framebuf_backend(), capabilities(), implementation()

License

MIT (framebuf algorithms derived from MicroPython extmod/modframebuf.c, Damien P. George).


Build from source

Layout

pygraphics/
  micropython.mk / micropython.cmake / circuitpython.mk / setup.py
  src/                     # C sources + headers (gfx_*.h, font_8x*.h, qstrs)
  lib/pygraphics/            # pure-Python package (import pygraphics)
  tests/                   # native smoke / parity tests
  tools/                   # developer benchmarks / helpers
  docs/ scripts/ web/

CPython native (editable)

python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/python tests/test_area.py
.venv/bin/python tests/test_pygraphics.py
.venv/bin/python tests/test_subclass.py

Pure Python (no extension)

PYTHONPATH=lib python3 -c "import pygraphics; print(pygraphics.implementation())"

Parity testing (native vs pure-Python)

micropython tools/compare_graphics_run.py    # single runtime
python tools/compare_graphics_matrix.py      # all desktop runtimes
micropython tools/compare_framebuf_mp.py     # C framebuf vs lib/pygraphics/framebuf.py

MicroPython

Clone as a sibling of micropython/:

workspace/
  pygraphics/     ← this repo
  micropython/
cd micropython/ports/unix
make submodules
make USER_C_MODULES=../../..
cd ../../..
./micropython/ports/unix/build-standard/micropython pygraphics/tests/test_area.py

CircuitPython (unix)

Adafruit’s Extending CircuitPython guide (and the design guide — native modules) describe adding shared-bindings/ + shared-module/ inside the CircuitPython tree. This repo keeps those sources out-of-tree under src/circuitpython_spike/ and applies them with ./apply_cp_patches.sh into a local (uncommitted) CircuitPython clone — Adafruit has no separate out-of-tree C-module path.

Adafruit stepThis repo
shared-bindings/<mod>/src/circuitpython_spike/shared-bindings/pygraphics/
shared-module/<mod>/src/circuitpython_spike/shared-module/pygraphics/
Enable CIRCUITPY_*Patches set CIRCUITPY_PYGRAPHICS
List sources in port MakefileVariant .mk + SRC_PATTERNS
Buildmake after --apply

Clone as a sibling of circuitpython/:

# siblings: circuitpython/ and pygraphics/
./apply_cp_patches.sh --apply
cd ../circuitpython/ports/unix && make -j VARIANT=coverage

See the cmods workspace for an easier way to build this repo with other user C modules (MicroPython) or extensions (CircuitPython).

pydevices-examples integration

When this cmod is installed or linked, pygraphics.framebuf_backend() reports native and pygraphics.implementation() reports native_cmod. Otherwise the pure-Python package reports pygraphics_python.