Skip to main content

The Grammar of Graphics — one engine, spoken from Python

Project description

gog for Python

The Grammar of Graphics, spoken from Python. A plot is a sentence — a table, a mark, and the channels that bind the mark to the table's columns:

from gog import *

gapminder = {"gdp": [...], "life": [...], "continent": [...]}

(data(gapminder) + point + x(col.gdp, scale="log") + y(col.life)
 + color(col.continent) + size(col.population)).save("life.svg")

The same sentence in R is data(gapminder) + point + x(gdp) + y(life) + color(continent) + size(population). Both build the same specification and hand it to the same engine, so the plots are identical to the byte. Nothing about what a plot means lives in this package — the grammar, the legality rules and the diagnostics are all gog-core's. Read the manual in book/; it is written in R, and every sentence in it translates by the rule below.

Installing

The wheel carries the engine. gog is a bridge to a Rust binary, and a package that installs but cannot draw is no package at all, so a release wheel ships the gog-cli built for its own platform. Installing needs no Rust toolchain and no checkout:

pip install gog          # once the wheels are published

The wheels are built by .github/workflows/python-wheels.yml, one per platform (macOS arm64 and x86_64, manylinux x86_64 and aarch64, Windows x64), and each job proves the wheel draws in a fresh environment before uploading it.

To build one yourself, or to work from a checkout:

cargo build --release -p gog-cli          # the engine
uv build --wheel py-pkg/gog               # a wheel carrying it
python3 -c "import sys; sys.path.insert(0, 'py-pkg/gog'); import gog"   # or just use the source

The engine is looked for in this order: GOG_CLI_PATH, the copy inside the installed package, gog-cli on PATH, then a local target/release build.

The two Python-specific things

A column is col.name. Python has no bare names, and in this grammar a plain string is a value (style(color="tomato"), title("…")). The accessor is what keeps "which column?" and "which value?" apart, so x("gdp") is refused and told what to write. Use col["life exp"] for a name Python cannot spell as an identifier.

from gog import * shadows five builtinsbin, sum, min, max and range are transforms here, the same way the R package masks base::range. A module that needs both can import gog and write gog.point, or take the builtin back with from builtins import sum.

Tables

A table is a dict of columns, or anything with .columns and df[name] — pandas and polars work without being imported, and without being required:

data({"x": [1.0, 2.0], "y": [3.0, 4.0]})        # stdlib only
data(pandas.read_csv("gapminder.csv"))          # duck-typed

Numbers become positions, text becomes categories, datetime/date become a calendar axis, a pandas Categorical carries its declared order, and None/ NaN is a missing value the engine drops with a message. A column that mixes numbers and text is refused, because a column is one type.

Tests

python3 py-pkg/gog/tests/test_basic.py            # from the repo root
python3 py-pkg/gog/tests/book_parity/run.py       # every sentence the manual teaches

The second one is the real check: it takes all 481 sentences from the book's 47 chapters, says each in Python, and compares against what R got. 379 byte-identical plots, 88 word-identical refusals, and no disagreements. See tests/book_parity/README.md — including the complete list of rewrites an R sentence needs, which is the honest measure of how far the two spellings are apart.

License

Apache License 2.0 — see LICENSE and NOTICE, which ship inside the package, so a copy taken from a registry carries them too.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

gog-0.0.1-py3-none-win_amd64.whl (839.2 kB view details)

Uploaded Python 3Windows x86-64

gog-0.0.1-py3-none-manylinux_2_28_x86_64.whl (1.0 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

gog-0.0.1-py3-none-manylinux_2_28_aarch64.whl (929.9 kB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

gog-0.0.1-py3-none-macosx_11_0_arm64.whl (890.2 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

gog-0.0.1-py3-none-macosx_10_12_x86_64.whl (972.5 kB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file gog-0.0.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: gog-0.0.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 839.2 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for gog-0.0.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 404f210aa353bb562e22293e55d62970bc9cbffbdd52262d298eb83696351daa
MD5 02c07446e368ea64781a4b0ffa85539f
BLAKE2b-256 f5706f7f85b78426847b0131b93c0e1b5fc9eb2f4bd931ad40e2494fb5c6f29f

See more details on using hashes here.

File details

Details for the file gog-0.0.1-py3-none-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: gog-0.0.1-py3-none-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: Python 3, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for gog-0.0.1-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d972a9f524b3c66bcb0cb2e65effe733c95109f36aa27335044fe13d4b500674
MD5 27aa4387fcdcc02796dc99c1a8e51dc9
BLAKE2b-256 e3f267f9f87f10292a14e54aeeeaaab82995b22513054a29eeade7b07252cb3c

See more details on using hashes here.

File details

Details for the file gog-0.0.1-py3-none-manylinux_2_28_aarch64.whl.

File metadata

  • Download URL: gog-0.0.1-py3-none-manylinux_2_28_aarch64.whl
  • Upload date:
  • Size: 929.9 kB
  • Tags: Python 3, manylinux: glibc 2.28+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for gog-0.0.1-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a6d292e757a8209f205308f445812baf40cf04299ae9b93bf209ec7aea9d63f0
MD5 3ad985e91b048916919e1fb91cd1f8c5
BLAKE2b-256 98288e729b9e7fe590c0e2f1443e9dbbd6a6debc67267d405d50a2fac9aff2f4

See more details on using hashes here.

File details

Details for the file gog-0.0.1-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: gog-0.0.1-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 890.2 kB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for gog-0.0.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b08c89fc0ab4ee8bf99c1039e7aac356efb297d3e83e6d3ef5e3fc1a44b70eb0
MD5 2d3ce6ebd88bedfcff100c9caebcebbe
BLAKE2b-256 95df88f16190ee62f2ee7a77ec889fc47de638106e7e553de70b197af68f5628

See more details on using hashes here.

File details

Details for the file gog-0.0.1-py3-none-macosx_10_12_x86_64.whl.

File metadata

  • Download URL: gog-0.0.1-py3-none-macosx_10_12_x86_64.whl
  • Upload date:
  • Size: 972.5 kB
  • Tags: Python 3, macOS 10.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for gog-0.0.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 73c7ecd812123c4fd8472ce9ed5d44a50e9f1cf0434f7e59f2bd05588c41f1c2
MD5 5dee0a8c83fe263d9a76ecd02b0e89ff
BLAKE2b-256 9339a195d1b1e1e081e80607a4e6e6e3b0b65dc3b3aa8d2e577b83dcc955f87a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page