Skip to main content
Ctrl+K

ggstyle 0.5.0

  • Getting started
  • User guide
  • Gallery
  • Semantic rendering gallery
  • Facet planning and rendering
    • Inspection
    • Choosing and migrating
    • Usability evidence
    • Graphics and reporting principles
    • Compatibility contract
    • Pitfalls
    • API reference
    • Release notes
  • GitHub
  • Getting started
  • User guide
  • Gallery
  • Semantic rendering gallery
  • Facet planning and rendering
  • Inspection
  • Choosing and migrating
  • Usability evidence
  • Graphics and reporting principles
  • Compatibility contract
  • Pitfalls
  • API reference
  • Release notes
  • GitHub

Section Navigation

  • Gallery

Gallery#

Every image on this page is generated from examples/finishing_gallery.py. The documentation and release jobs execute the source in a temporary directory, while python tools/validate_gallery.py --write deliberately refreshes the reviewed assets.

Publication finishing#

The publication-finishing gallery combines coherent title hierarchy, explicit currency and percentage semantics, collision-aware endpoint labels, and the public palette policies. Every panel remains an ordinary Matplotlib Axes.

Four panels showing coherent labels, direct endpoint labels, percent labels, and palettes

Theme comparison#

All nine themes share a type scale and qualitative cycle. Theme changes affect the non-data surface while the plotted series keep their visual identity.

Nine-panel comparison of every ggstyle theme

Executable source#

examples/finishing_gallery.py#
"""Generate the checked-source v0.4 publication-finishing gallery."""

from __future__ import annotations

import argparse
from pathlib import Path

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.figure import Figure
from matplotlib.patches import Rectangle

import ggstyle as gs


def finishing_figure() -> Figure:
    """Build labels, direct labels, numeric formats, and palette examples."""
    with gs.theme(gs.theme_spec("minimal", base_size=10)):
        figure, axes = plt.subplots(
            2,
            2,
            figsize=(9, 6.5),
            dpi=120,
            layout="constrained",
        )

    periods = np.arange(1, 9)
    revenue = np.array([2.1, 2.3, 2.6, 2.5, 2.9, 3.2, 3.4, 3.8]) * 1_000_000
    axes[0, 0].plot(periods, revenue, marker="o")
    gs.finish(
        axes[0, 0],
        title="Coherent labels",
        subtitle="Native axes, managed hierarchy",
        caption="Source: illustrative data",
        x=gs.axis(title="Quarter"),
        y=gs.axis(
            title="Revenue",
            labels=gs.label_currency("$", scale=1_000_000, decimals=1, suffix="M"),
        ),
    )

    direct = axes[0, 1]
    series = (
        ("North", [1.0, 1.5, 1.8, 2.2, 2.7, 3.04]),
        ("Central", [1.3, 1.7, 2.0, 2.4, 2.8, 3.00]),
        ("South", [0.8, 1.2, 1.7, 2.1, 2.6, 2.96]),
    )
    for label, values in series:
        direct.plot(np.arange(6), values, marker="o", label=label)
    gs.finish(
        direct,
        title="Collision-aware direct labels",
        direct_labels=gs.end_labels(),
        x=gs.axis(title="Period"),
        y=gs.axis(title="Index"),
    )

    share = axes[1, 0]
    categories = ["A", "B", "C", "D"]
    values = np.array([0.18, 0.27, 0.31, 0.24])
    share.bar(categories, values, color=gs.palette("sequential", n=4).colors)
    gs.finish(
        share,
        title="Explicit numeric semantics",
        y=gs.axis(title="Share", labels=gs.label_percent(decimals=0)),
    )

    palette_axis = axes[1, 1]
    selected = (
        gs.palette("qualitative"),
        gs.palette("sequential", n=8),
        gs.palette("diverging", n=9),
    )
    for row, palette in enumerate(selected):
        for column, color in enumerate(palette.colors):
            palette_axis.add_patch(Rectangle((column, row), 1, 0.72, color=color))
        palette_axis.text(-0.15, row + 0.36, palette.name, ha="right", va="center")
    palette_axis.set_xlim(-1.2, 9)
    palette_axis.set_ylim(-0.15, 3)
    palette_axis.set_title("Accessible palette policies", loc="left")
    palette_axis.axis("off")
    return figure


def theme_figure() -> Figure:
    """Build a compact comparison of every packaged theme."""
    figure = plt.figure(figsize=(9, 7), dpi=120, facecolor="white", layout="constrained")
    x = np.arange(4)
    for index, name in enumerate(gs.available_themes(), start=1):
        with gs.theme(name):
            ax = figure.add_subplot(3, 3, index)
            ax.plot(x, [0.8, 2.2, 1.5, 2.7], marker="o")
            ax.plot(x, [2.4, 1.7, 2.6, 1.1], marker="s")
            ax.set_title(name)
            ax.set_xlim(-0.2, 3.2)
            ax.set_ylim(0.5, 3.0)
            ax.set_xticks([0, 1, 2, 3])
            ax.set_yticks([1, 2, 3])
    return figure


def render(output_directory: Path) -> tuple[Path, Path]:
    """Render every gallery figure into an existing output directory."""
    destinations = (
        output_directory / "finishing_gallery.png",
        output_directory / "theme_gallery.png",
    )
    for builder, destination, size in (
        (finishing_figure, destinations[0], (9.0, 6.5)),
        (theme_figure, destinations[1], (9.0, 7.0)),
    ):
        figure = builder()
        try:
            gs.save(
                figure,
                destination,
                width=size[0],
                height=size[1],
                dpi=120,
                bbox="standard",
                metadata={"Creator": "ggstyle v0.4 gallery"},
                overwrite=True,
            )
        finally:
            plt.close(figure)
    return destinations


def main() -> None:
    """Render gallery images beside this script or into an explicit directory."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--output-dir", type=Path, default=Path(__file__).parent)
    arguments = parser.parse_args()
    for destination in render(arguments.output_dir):
        print(destination)


if __name__ == "__main__":
    main()

previous

User guide

next

Semantic rendering gallery

On this page
  • Publication finishing
  • Theme comparison
  • Executable source
Show Source

© Copyright 2026, Joshua Myers.

Created using Sphinx 9.1.0.

Built with the PyData Sphinx Theme 0.21.0.