Skip to content

Bio-Babel/ggplot2-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

110 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ggplot2_py ggplot2_py logo

PyPI

AI-assisted Python port of the R ggplot2 package — Create Elegant Data Visualisations Using the Grammar of Graphics.

Overview

ggplot2_py implements the grammar of graphics in Python, faithfully porting R's ggplot2 using pandas DataFrames as the data container and a Cairo-based rendering backend. It supports 47 geoms, 32 stats, faceting, coordinate systems, themes, guides, and 130+ scales.

Beyond a direct port, ggplot2_py adds Python-exclusive features that extend the Grammar of Graphics with Python-native idioms while preserving full orthogonality of GOG components.

Python-Exclusive Features

These capabilities have no R equivalent and leverage Python-specific language features:

Feature Python mechanism What it enables
Callable aes() expressions First-class functions / lambdas aes(y=lambda d: np.log(d["mpg"])) — inline data transforms without pre-computing columns
after_stat() / after_scale() callables Same after_stat(lambda d: d["count"] / d["count"].sum()) — arbitrary expressions at each pipeline stage
singledispatch extensibility functools.singledispatch @update_ggplot.register(MyClass) — any Python class can be added to a plot with +
Build hooks Dict-keyed callback lists plot.add_build_hook("after", BuildStage.COMPUTE_STAT, fn) — intercept data at any of 16 named pipeline stages
Auto-registration __init_subclass__ class GeomStar(Geom): ... auto-registers; no manual wiring needed
Protocol contracts typing.Protocol isinstance(my_geom, GeomProtocol) — structural type checking for extensions
Scoped defaults contextvars.ContextVar with ggplot_defaults(theme=theme_minimal()): ... — thread-safe scoped defaults

Installation

# From PyPI
pip install ggplot2-python

For a local development:

git clone https://github.com/Bio-Babel/ggplot2-python.git
cd ggplot2_py
pip install -e ".[dev]"

Quick Start

from ggplot2_py import *
from ggplot2_py.datasets import mpg

(ggplot(mpg, aes(x="displ", y="hwy", colour="class"))
 + geom_point()
 + geom_smooth(method="lm")
 + facet_wrap("drv")
 + theme_minimal()
 + labs(title="Engine Displacement vs Highway MPG"))

Callable expressions in aes (Python-exclusive)

import numpy as np
from ggplot2_py import ggplot, aes, geom_point, geom_histogram, after_stat

# Inline data transform — no need to pre-compute a column
ggplot(mpg, aes(x=lambda d: np.log(d["displ"]), y="hwy")) + geom_point()

# Normalised histogram — callable in after_stat
(ggplot(mpg, aes(x="hwy"))
 + geom_histogram(aes(y=after_stat(lambda d: d["count"] / d["count"].sum())), bins=15))

Extending with custom types (Python-exclusive)

from ggplot2_py import update_ggplot

class Watermark:
    def __init__(self, text): self.text = text

@update_ggplot.register(Watermark)
def _add_watermark(obj, plot, object_name=""):
    plot.labels["caption"] = f"[{obj.text}]"
    return plot

# Now use with +
ggplot(mpg, aes("displ", "hwy")) + geom_point() + Watermark("DRAFT")

Scoped defaults (Python-exclusive)

from ggplot2_py import ggplot_defaults

with ggplot_defaults(theme=theme_minimal()):
    p1 = ggplot(df, aes("x", "y")) + geom_point()   # theme_minimal applied
    p2 = ggplot(df, aes("x", "y")) + geom_bar()     # theme_minimal applied
# Outside: no defaults

Tutorials

User Tutorials

  • Getting Started — core concepts: data, aes, geoms, stats, scales, facets, coords, themes
  • Geom Gallery — boxplot, violin, density, tile, hex and combinations
  • Labels & Facets — axis titles, plot title/subtitle/caption, facet strip labels
  • Aesthetic Specs — colour, fill, alpha, linetype, shape, size, colour scales
  • Extending ggplot2 — custom stats, geoms, themes via ggproto

Python-Exclusive Feature Tutorials

Developer Guide

  • Developer Guide: Extending ggplot2_py — comprehensive guide covering ggproto system, custom Stat/Geom creation, Protocol contracts, singledispatch, hooks, auto-registration, context manager, and packaging

Extension Architecture

ggplot2_py is designed as an extensible platform. The following table summarises all extension points:

Extension point Mechanism How to use
Custom Stat Subclass Stat Override compute_group() — auto-registered via __init_subclass__
Custom Geom Subclass Geom Override draw_panel() — auto-registered
Custom Scale Subclass ScaleContinuous / ScaleDiscrete Implement train(), map(), get_breaks()
Custom Coord Subclass Coord Override transform(), setup_panel_params()
Custom Facet Subclass Facet Override compute_layout(), map_data()
Custom Position Subclass Position Override compute_layer() — auto-registered
Custom + types @update_ggplot.register(MyClass) Register any Python class for the + operator
Custom plot types @ggplot_build.register(MyPlot) Override the entire build pipeline
Build hooks plot.add_build_hook(timing, stage, fn) Intercept data at any pipeline stage
Protocol validation isinstance(obj, GeomProtocol) Verify structural conformance
Scoped defaults with ggplot_defaults(theme=...): Thread-safe scoped defaults

About

ggplot2-python, full original taste of R ggplot2

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages