TOC »
- gg-plot
- Module: gg-plot
- Module: gg-primitives-vge
- Module: gg-backend-cairo
- Module: gg-scales
- Module: gg-data
- Module: gg-aes
- Module: gg-geom
- Module: gg-guides
- Data format
- Examples
- Minimal scatter plot
- Time series with confidence ribbon
- Multi-series line plot with manual colors
- Bar chart with categorical x axis
- Spike raster (neuroscience event plot)
- Logarithmic axes
- Faceted plot (small multiples)
- Multiple output formats
- Plot specification serialisation
- Programmatic plot generation
- Architecture notes
gg-plot
A declarative plotting system built on top of the Cairo graphics library which provides ggplot2-style plotting routines, with s-expression plot specifications, automatic scale training, and four output formats (PNG, SVG, PostScript, PDF).
Requirements
- cairo (Cairo graphics bindings)
- matchable
- datatype
- yasos
- statistics
Overview
The library is organised into nine modules that correspond to the tiers of the Grammar of Graphics. Most users only need to (import gg-plot); the lower-level modules are available for custom rendering pipelines.
- gg-plot
- Full declarative plot API
- gg-vge
- Virtual Graphics Engine — algebraic IR for graphics instructions
- gg-backend
- Abstract backend protocol (YASOS interface)
- gg-backend-cairo
- Cairo backend; PNG, SVG, PostScript, and PDF output
- gg-primitives-vge
- Composable drawer abstraction; shapes, text, transforms
- gg-scales
- Data-to-visual mappings (linear, log, ordinal, color)
- gg-data
- Columnar data utilities
- gg-aes
- Aesthetic (column-channel) mapping
- gg-geom
- Geometry functions (scatter, line, bar, errorbar, raster...)
- gg-guides
- Axis and legend drawers
The translation pipeline
s-expression spec -> normalize / validate defaults -> train scales from all layers -> compute facet panels -> render each panel (background, geometries, axes) -> render global elements (title, legends) -> emit via Cairo (PNG / SVG / PS / PDF)
Module: gg-plot
The top-level declarative API. Import only this module for typical use.
(import gg-plot)Plot construction
- ggplot data #!rest specsprocedure
Create a plot-spec record.
data is a columnar alist. specs is a mixed list of:
- an (aes ...) call for the default aesthetic mapping,
- layer constructors (layer-point, layer-line, …),
- scale specifications (scale-x-continuous, …),
- a coordinate system (coord-cartesian, …),
- a faceting specification (facet-wrap, facet-grid),
- a theme (theme-minimal, …),
- (labs ...) for title and axis labels.
(define p (ggplot data (aes #:x 'time #:y 'value #:color 'condition) (layer-line #:width 2) (layer-point #:size 5) (scale-x-continuous #:name "Time (ms)") (scale-y-continuous #:name "Response (mV)") (scale-color-manual #:values '(("Control" . "blue") ("Treatment" . "red"))) (theme-minimal #:base-size 12) (labs #:title "Treatment vs Control")))
Rendering
- render-plot plot-spec backendprocedure
Execute the full rendering pipeline and write output. backend is a Cairo backend constructed with one of the make-cairo-*-backend procedures from gg-backend-cairo.
- ggsave plot-spec filename #!key width height format scaleprocedure
Save to a file. format is inferred from the extension (.png, .svg, .ps) or can be given explicitly as 'png, 'svg, or 'ps. width/height default to 800×600.
- ggdisplay plot-spec #!key width heightprocedure
Render to an X11 window.
Plot serialisation
- plot->sexp plot-specprocedure
Convert a plot specification to a pure s-expression (no closures). The result can be written to a file with write and read back later.
- sexp->plot sexpprocedure
Reconstruct a plot-spec from a serialised s-expression.
Layer constructors
All layer constructors accept #:data (override dataset), #:mapping (override or extend the plot-level aesthetic mapping), plus geometry-specific keyword arguments.
Basic geometries
- layer-point #!key data mapping size shape alpha colorprocedure
- layer-line #!key data mapping width style colorprocedure
- layer-path #!key data mapping width colorprocedure
- layer-area #!key data mapping fill alphaprocedure
- layer-bar #!key data mapping fill widthprocedure
- layer-rect #!key data mapping fill colorprocedure
- layer-text #!key data mapping size colorprocedure
- layer-segment #!key data mapping color widthprocedure
- layer-eventplot #!key data mapping line-length width colorprocedure
Reference lines
- layer-hline yintercept #!key color width linetype alphaprocedure
- layer-vline xintercept #!key color width linetype alphaprocedure
linetype is 'solid, 'dashed, or 'dotted.
Statistical geometry layers
- layer-histogram #!key data mapping bins binwidth breaks method fill color alphaprocedure
- bins
- number of bins (default 30)
- binwidth
- bin width in data units (overrides bins)
- method
- 'sturges (default), 'scott, 'fd, 'equal-width
- layer-density #!key data mapping bandwidth kernel n adjust fill color alphaprocedure
- kernel
- 'gaussian (default), 'epanechnikov, 'rectangular, 'triangular, 'biweight
- n
- number of evaluation points (default 512)
- layer-boxplot #!key data mapping coef varwidth fill color outlier-color outlier-size widthprocedure
- coef
- IQR multiplier for whisker length (default 1.5)
- layer-violin #!key data mapping scale draw-quantiles bandwidth kernel fill color alphaprocedure
- scale
- 'area (equal area, default) or 'count (proportional to n)
- draw-quantiles
- list of quantile levels, e.g. '(0.25 0.5 0.75)
- layer-errorbar #!key data mapping stat fun-ymin fun-ymax color width cap-widthprocedure
- stat
- 'identity (use ymin/ymax columns) or 'summary (compute from raw values)
- layer-pointrange #!key data mapping stat fun-y fun-ymin fun-ymax color point-size line-widthprocedure
- layer-linerange #!key data mapping stat fun-ymin fun-ymax color widthprocedure
- layer-crossbar #!key data mapping stat fun-y fun-ymin fun-ymax fill color widthprocedure
- layer-col #!key data mapping fun position fill color widthprocedure
- position
- 'stack (default), 'dodge, 'fill
Annotation layers
- layer-annotate-text text x y #!key size color hjust vjust angleprocedure
- layer-annotate-rect xmin ymin xmax ymax #!key fill alpha color line-widthprocedure
- layer-annotate-segment x1 y1 x2 y2 #!key color widthprocedure
- layer-annotate-arrow x1 y1 x2 y2 #!key color widthprocedure
Coordinates are in data space.
For reference lines with full linetype support, the following are recommended over layer-hline/layer-vline when annotation-layer dispatch is needed:
- annotate-vline x #!key color width linetypeprocedure
- annotate-hline y #!key color width linetypeprocedure
- annotate-abline slope intercept #!key color widthprocedure
Scale specifications
Scale specification functions return tagged lists consumed by ggplot.
Continuous position scales
- scale-x-continuous #!key name limits breaks trans expandprocedure
- scale-y-continuous #!key name limits breaks trans expandprocedure
- name
- axis title string
- limits
- explicit domain (min max)
- breaks
- explicit tick positions
- trans
- transformation symbol: 'log, 'log10, 'sqrt, …
- expand
- fractional padding added to domain on each side
- scale-x-log #!key name base breaksprocedure
- scale-y-log #!key name base breaksprocedure
Shorthand for a continuous scale with trans: 'log and the given base (default 10).
Discrete position scales
- scale-x-discrete #!key name limitsprocedure
- scale-y-discrete #!key name limitsprocedure
Color / fill scales
- scale-color-manual #!key valuesprocedure
- scale-fill-manual #!key valuesprocedure
values is an alist: '(("Control" . "blue") ("Treatment" . "red")).
- scale-color-gradient #!key low high limitsprocedure
Two-stop continuous gradient.
Coordinate systems
- coord-cartesian #!key xlim ylimprocedure
Default Cartesian coordinates with optional axis limits.
- coord-fixed #!key ratio xlim ylimprocedure
Fixed aspect ratio (default 1:1).
- coord-flipprocedure
Swap x and y axes.
Faceting
- facet-nullprocedure
No faceting (single panel, default).
- facet-wrap var #!key ncol nrow scalesprocedure
Wrap panels by var (a quoted symbol). scales is one of "fixed" (default), "free", "free_x", "free_y".
- facet-grid row-var col-var #!key scales space shrink labellerprocedure
Two-dimensional panel grid. Pass #f for either variable to omit that dimension.
Themes
- theme-gray #!key base-size base-familyprocedure
Gray background with white grid lines (the default ggplot2-style theme).
- theme-minimal #!key base-size base-familyprocedure
White background, no border, gray grid lines. base-size defaults to 11.
- theme-classic #!key base-size base-familyprocedure
White background, no grid lines, axis lines present.
- theme-bw #!key base-sizeprocedure
White background, black border, gray grid lines.
- theme-linedraw #!key base-size base-familyprocedure
White background, black grid lines and border.
- theme-light #!key base-size base-familyprocedure
Light gray border and grid lines.
- theme-dark #!key base-size base-familyprocedure
Dark background with contrasting grid lines; suitable for bright-colored data.
- theme-void #!key base-sizeprocedure
No background, no axes, no grid.
Legend position modifiers
- theme-legend-position positionprocedure
position: 'right (default), 'left, 'top, 'bottom, 'none, 'inside, 'outside.
- theme-legend-inside positionprocedure
position: 'top-right, 'top-left, 'bottom-right, 'bottom-left, 'center.
- theme-legend-outside positionprocedure
position: 'right, 'left, 'top, 'bottom.
Labels
- labs #!key title subtitle x y captionprocedure
- xlab nameprocedure
- ylab nameprocedure
- ggtitle title #!optional subtitleprocedure
Collision-avoiding text
- geom-text-repel ...procedure
- geom-label-repel ...procedure
Repel overlapping text labels using a force-directed algorithm. Accepts the same arguments as layer-text.
Plot-spec accessors
- plot-spec? objprocedure
- plot-spec-data specprocedure
- plot-spec-default-aes specprocedure
- plot-spec-layers specprocedure
- plot-spec-scales specprocedure
- plot-spec-coord specprocedure
- plot-spec-facet specprocedure
- plot-spec-theme specprocedure
- plot-spec-labels specprocedure
Module: gg-primitives-vge
Low-level composable drawing layer. A drawer is a record wrapping a procedure that emits instructions into a VGE (Virtual Graphics Engine). Drawers are first-class values: they can be stored, composed with combine, and wrapped with style or transform combinators before being rendered to any backend.
Coordinate convention: right-handed, origin at bottom-left, Y-up. All coordinates are in user space; the backend maps them to device pixels.
Drawer record
- make-drawer proc boundsprocedure
Create a drawer from a procedure (vge -> void) and an optional bounding box (or #f).
- drawer? objprocedure
True if obj is a drawer record.
- drawer-proc drawerprocedure
- drawer-bounds drawerprocedure
Accessors.
- empty-drawerprocedure
A drawer that does nothing (identity for combine).
Composition
- combine drawer ...procedure
Return a new drawer that executes each argument drawer left-to-right with no additional scoping.
- combine-group drawer ...procedure
Like combine but wraps the result in a gfx:group scope.
Rendering
- render-drawer drawer vgeprocedure
Emit a drawer's instructions into vge (a VGE accumulator created by make-vge from gg-vge). Does not perform I/O; call vge-render! afterwards to send the instructions to a backend.
Scoped state wrappers
Each wrapper produces a gfx:group, so the state change is automatically scoped; no explicit push/pop is needed.
- with-pushed-state drawerprocedure
Raw push/pop scope (low-level; prefer the typed wrappers below).
- with-translate dx dy drawerprocedure
- with-viewport x0 y0 x1 y1 drawerprocedure
- with-clip-rect x y w h drawerprocedure
- with-rotate angle drawerprocedure
angle in radians.
Style wrappers
- with-pen-color color drawerprocedure
color is a color string ("steelblue", "#3f7ab5") or a color:rgba / color:named value from gg-backend.
- with-fill-color color drawerprocedure
- with-line-width width drawerprocedure
width in user coordinates.
- with-dash dashes offset drawerprocedure
dashes is a list of on/off lengths; offset is the phase.
- with-font family size slant weight drawerprocedure
family is a font family string (e.g. "sans-serif"); slant is 'normal or 'italic; weight is 'normal or 'bold.
Stroked drawing primitives
- line-drawer x1 y1 x2 y2procedure
- polyline-drawer ptsprocedure
pts is a list of (x . y) pairs.
- rect-drawer x y w hprocedure
Outline rectangle; bottom-left corner at (x, y).
- circle-drawer cx cy rprocedure
- polygon-drawer ptsprocedure
Filled drawing primitives
- filled-rect-drawer x y w hprocedure
- filled-circle-drawer cx cy rprocedure
- filled-polygon-drawer ptsprocedure
Text
- text-drawer x y text #!key halign valignprocedure
Draw text anchored at (x, y).
- halign
- 'left, 'center (default), or 'right
- valign
- 'top, 'center, 'bottom, or 'baseline (default)
Convenience drawers
- h-line-drawer x1 x2 yprocedure
- v-line-drawer x y1 y2procedure
- filled-rect+border-drawer x y w h fill-color edge-colorprocedure
- path-drawer cmds #!key filled?procedure
cmds is a list of path commands from gg-backend: path:move-to, path:line-to, path:curve-to, path:arc, path:close.
Module: gg-backend-cairo
Cairo graphics backend. Implements the abstract backend protocol from gg-backend for four output formats.
- make-cairo-png-backend filename width heightprocedure
PNG raster output. width and height are in pixels.
- make-cairo-svg-backend filename width heightprocedure
SVG vector output.
- make-cairo-ps-backend filename width heightprocedure
PostScript output.
- make-cairo-pdf-backend filename width heightprocedure
PDF output. width and height are in points (72 pt = 1 inch; A4 portrait = 595 × 842 pt).
Module: gg-scales
Scales map between the data domain and the visual range. All scale objects implement the same protocol (via YASOS), so geometry and guide code is scale-type–agnostic.
Scale protocol
- scale? objprocedure
- scale-type scaleprocedure
Returns a symbol: 'linear, 'log, 'sqrt, 'power, 'ordinal, 'band, 'color-gradient, 'color-manual, …
- scale-train! scale valuesprocedure
Extend the domain to include values (a list). Mutates the scale.
- scale-map scale valueprocedure
Map a single domain value to the visual range.
- scale-inverse scale valueprocedure
Map from visual range back to domain.
- scale-breaks scale #!optional nprocedure
Return a list of n (default 5) nicely-placed tick positions.
- scale-labels scale breaksprocedure
Return formatted label strings for the given break positions.
- scale-domain scaleprocedure
Current domain as a (min . max) pair, or a list for discrete scales.
- scale-range scaleprocedure
Current visual range as a (min . max) pair.
- scale-set-domain! scale domainprocedure
- scale-set-range! scale rangeprocedure
Mutating setters.
- scale-bandwidth scaleprocedure
Width of a single band (for band scales only).
Functional scale combinators
These return a new scale and leave the original unmodified.
- scale-with-domain scale domainprocedure
- scale-with-range scale rangeprocedure
- scale-with-trained scale valuesprocedure
- scale-with-transform scale transform-typeprocedure
transform-type is one of: 'log, 'log10, 'log2, 'ln, 'sqrt, 'identity.
- scale-with-breaks scale explicit-breaksprocedure
Override automatic break computation with a fixed list.
Continuous scale constructors
- make-scale-linear #!key domain rangeprocedure
- make-scale-log #!key domain range baseprocedure
base defaults to 10.
- make-scale-sqrt #!key domain rangeprocedure
- make-scale-power #!key domain range exponentprocedure
exponent defaults to 2.
Discrete scale constructors
- make-scale-ordinal #!key domain rangeprocedure
Maps each domain value to the corresponding entry in range, cycling if necessary.
- make-scale-band #!key domain range paddingprocedure
Like ordinal but maps to a continuous sub-interval (band) for bar charts. padding (default 0.1) is the fraction of each step reserved for spacing.
Color scale constructors
- make-scale-color-gradient #!key domain low highprocedure
Continuous gradient interpolating between low and high color strings. Accepts named colors ("blue") and hex strings ("#3f7ab5").
- make-scale-color-diverging #!key domain low mid high midpointprocedure
Two-segment gradient with a midpoint color.
- make-scale-color-ordinal #!key domain paletteprocedure
Ordinal scale backed by a list of color strings.
- make-scale-color-manual value-mapprocedure
Explicit category -> color alist, e.g. `(("Control" . "blue") ("Treatment" . "red"))
Break utilities
- nice-breaks min-val max-val nprocedure
- compute-pretty-breaks min max nprocedure
- extend-domain domain expansionprocedure
Extend domain by the fractional expansion on each side (e.g. 0.05 adds 5 % padding).
Module: gg-data
Columnar data frames: an association list mapping column names (symbols) to parallel value lists.
(define data
'((time . (0 10 20 30 40 50))
(value . (1.2 1.5 2.3 1.8 1.4 1.9))
(group . ("A" "A" "A" "B" "B" "B"))))
- data-column data column-nameprocedure
Extract a column list. Signals an error if the column is absent.
- data-columns dataprocedure
List of column name symbols.
- data-n-rows dataprocedure
- data-row data indexprocedure
Single row as an association list ((col . value) ...).
- data-rows dataprocedure
All rows as a list of association lists. Used internally by geometries.
- columns->rows dataprocedure
- rows->columns rowsprocedure
Convert between the columnar and row-oriented representations.
Module: gg-aes
Aesthetic mappings link data columns to visual channels.
Creating mappings
- aes #!key x y color fill size shape alpha linetype group labelprocedure
- make-aes ...procedure
Both are equivalent. Column references are symbols; literal values are strings or numbers:
(aes #:x 'time #:y 'value #:color 'condition) ; x, y, color mapped to columns (aes #:x 'time #:y 'value #:color "steelblue") ; color is a constant
- aesthetic-mapping? objprocedure
Accessors
- aes-x mappingprocedure
- aes-y mappingprocedure
- aes-color mappingprocedure
- aes-fill mappingprocedure
- aes-size mappingprocedure
- aes-shape mappingprocedure
- aes-alpha mappingprocedure
- aes-linetype mappingprocedure
- aes-group mappingprocedure
- aes-label mappingprocedure
- aes-get mapping key #!optional defaultprocedure
Utilities
- aes-merge base overrideprocedure
Merge two mappings; override wins on conflicts.
- aes-has? mapping keyprocedure
- aes-keys mappingprocedure
- aes-map-value mapping key data-rowprocedure
Resolve an aesthetic: if the stored value is a symbol, look it up in data-row (an association list); otherwise return the literal value.
- constant-value? valueprocedure
- mapped-value? valueprocedure
Module: gg-geom
Geometry functions take a columnar data frame and an aesthetic mapping and return (values drawer trained-scales). They are normally used indirectly through the layer constructors in gg-plot, but can be called directly for custom pipelines.
Core geometries
- geom-point data aes #!key scales size shape alphaprocedure
Scatter plot. Required aesthetics: x, y. Optional: color, fill, size.
- geom-line data aes #!key scales width styleprocedure
Line plot. Groups rows by the color or group aesthetic and draws a separate polyline per group. Required: x, y.
- geom-path data aes #!key scales width colorprocedure
Like geom-line but connects points in data order without sorting.
- geom-area data aes #!key scales fill alphaprocedure
Filled area. With only x/y aesthetics, fills from 0 to y (simple area). With ymin/ymax aesthetics, fills between the two curves (ribbon).
- geom-bar data aes #!key scales fill widthprocedure
Bar chart. Required: x, y.
- geom-rect data aes #!key scalesprocedure
Draws rectangles from xmin/xmax/ymin/ymax aesthetics.
- geom-text data aes #!key scales size colorprocedure
Text labels positioned at x/y, string from label aesthetic.
- geom-segment data aes #!key scales color widthprocedure
Line segments from (x, y) to (xend, yend).
- geom-hline data aes #!key scales color width linetypeprocedure
- geom-vline data aes #!key scales color width linetypeprocedure
Reference lines.
Event plot
- geom-eventplot data aes #!key scales line-length width colorprocedure
Draws one vertical tick per event time. Expects x to hold a list of timestamps per row and y to hold the row index (trial number).
(define spike-data '((trial . (0 1 2 3 4)) (spikes . ((12 25 38) (15 28 42) (10 23 40) (18 30 45) (13 27 41))))) (geom-eventplot spike-data (aes #:x 'spikes #:y 'trial) #:line-length 0.7 #:width 1 #:color "black")
Statistical geometries
- geom-histogram data aes #!key scales bins fill color alphaprocedure
- geom-density data aes #!key scales fill color alphaprocedure
- geom-boxplot data aes #!key scales fill color widthprocedure
- geom-violin data aes #!key scales fill color alphaprocedure
- geom-errorbar data aes #!key scales color width cap-widthprocedure
- geom-crossbar data aes #!key scales fill color widthprocedure
- geom-linerange data aes #!key scales color widthprocedure
- geom-pointrange data aes #!key scales color point-size line-widthprocedure
Module: gg-guides
Axis and legend rendering. Returns drawers positioned in axis-local coordinates; gg-plot translates them to panel coordinates.
Axes
- make-axis-bottom scale #!key label tick-countprocedure
- make-axis-top scale #!key label tick-countprocedure
- make-axis-left scale #!key label tick-countprocedure
- make-axis-right scale #!key label tick-countprocedure
Convenience wrappers around:
- make-axis scale position #!key label tick-count tick-length tick-width label-size label-offset line-colorprocedure
- position
- 'bottom, 'top, 'left, or 'right
- tick-count
- target number of ticks (default 5)
- tick-length
- length of tick marks in user units (default 5)
- tick-width
- stroke width of ticks (default 1)
- label-size
- font size for tick labels (default 10.0)
- label-offset
- distance from axis line to label anchor in user units (default 15)
- line-color
- color string (default "black")
- axis-drawer axis-configprocedure
Return a drawer for the axis. The drawer is in axis-local coordinates (the axis line lies at x=0 for vertical axes, y=0 for horizontal ones); the caller must apply with-translate to place it at the panel edge.
Legends
- make-legend-continuous scale #!key title position width height label-sizeprocedure
- make-legend-discrete scale #!key title position width height label-sizeprocedure
- legend-drawer legend-configprocedure
Data format
All geometries expect data as a columnar alist, an association list mapping column names (symbols) to lists of equal length:
;; Columnar alist (required by the library) '((time . (0 10 20 30 40 50)) (response . (0.89 1.29 2.35 1.68 2.58 2.08)) (condition . ("A" "A" "A" "B" "B" "B")))
Use columns->rows / rows->columns from gg-data to convert between row-oriented and column-oriented representations.
Examples
Minimal scatter plot
(import gg-plot gg-backend-cairo) (define data '((x . (1 2 3 4 5)) (y . (2.1 3.8 2.9 5.1 4.3)))) (define p (ggplot data (aes #:x 'x #:y 'y) (layer-point #:size 6 #:color "steelblue") (scale-x-continuous #:name "X") (scale-y-continuous #:name "Y") (theme-minimal) (labs #:title "Simple Scatter"))) (ggsave p "scatter.png" #:width 600 #:height 400)
Time series with confidence ribbon
(import gg-plot gg-backend-cairo) (define data '((time . (0 10 20 30 40 50 60 70 80 90 100)) (value . (0.89 1.29 2.35 1.68 1.15 1.81 2.58 2.08 1.57 1.94 2.35)) (upper . (1.66 1.95 2.72 2.12 1.71 2.21 2.96 2.39 2.00 2.27 2.67)) (lower . (0.55 0.83 1.56 0.75 0.76 1.16 2.19 1.50 0.91 1.16 2.00)))) (define p (ggplot data (aes #:x 'time #:y 'value) ;; Shaded confidence band (layer-area #:mapping (aes #:ymin 'lower #:ymax 'upper) #:fill "steelblue" #:alpha 0.3) ;; Central line and points (layer-line #:width 2 #:color "black") (layer-point #:size 5 #:color "black") (scale-x-continuous #:name "Time (seconds)") (scale-y-continuous #:name "Response (mV)") (theme-minimal #:base-size 12) (labs #:title "Time Series with Confidence Band" #:subtitle "Example of layered composition"))) (ggsave p "timeseries.png" #:width 800 #:height 600)
Multi-series line plot with manual colors
(import gg-plot gg-backend-cairo) (define data '((time . (0 10 20 30 40 50 60 0 10 20 30 40 50 60)) (value . (1.2 2.3 1.8 2.5 2.1 1.9 2.4 0.8 1.5 1.2 1.8 1.6 1.4 1.7)) (condition . ("Control" "Control" "Control" "Control" "Control" "Control" "Control" "Treatment" "Treatment" "Treatment" "Treatment" "Treatment" "Treatment" "Treatment")))) (define p (ggplot data (aes #:x 'time #:y 'value #:color 'condition) (layer-line #:width 2) (layer-point #:size 4) (scale-x-continuous #:name "Time (ms)") (scale-y-continuous #:name "Response") (scale-color-manual #:values '(("Control" . "blue") ("Treatment" . "red"))) (theme-classic #:base-size 11) (labs #:title "Treatment vs Control"))) (ggsave p "multiseries.png" #:width 800 #:height 600)
Bar chart with categorical x axis
(import gg-plot gg-backend-cairo) (define data '((region . ("V1" "V2" "V4" "MT" "IT")) (firing-rate . (12.5 8.3 15.7 22.1 9.4)))) (define p (ggplot data (aes #:x 'region #:y 'firing-rate) (layer-bar #:fill "steelblue" #:width 0.7) (scale-x-discrete #:name "Brain Region") (scale-y-continuous #:name "Firing Rate (Hz)" #:limits '(0 25)) (theme-bw) (labs #:title "Firing Rates Across Brain Regions"))) (ggsave p "bars.png" #:width 700 #:height 500)
Spike raster (neuroscience event plot)
(import gg-plot gg-backend-cairo) (define spike-data '((trial . (0 1 2 3 4 5 6 7 8 9)) (spikes . ((12 25 38 55 67) (15 28 42 58 71) (10 23 40 52 65) (18 30 45 60 73) (13 27 41 56 68) (16 29 43 59 72) (11 24 39 54 66) (14 26 44 57 70) (17 31 46 61 74) (9 22 37 53 64))) (condition . ("Pre" "Pre" "Pre" "Pre" "Pre" "Post" "Post" "Post" "Post" "Post")))) (define p (ggplot spike-data (aes #:x 'spikes #:y 'trial #:color 'condition) (layer-eventplot #:line-length 0.7 #:width 4) ;; Stimulus onset marker (layer-vline #:xintercept 20 #:color "red" #:linetype 'dashed #:width 1.5) (scale-x-continuous #:name "Time (ms)" #:limits '(0 80)) (scale-y-continuous #:name "Trial #") (scale-color-manual #:values '(("Pre" . "black") ("Post" . "royalblue"))) (theme-classic #:base-size 11) (labs #:title "Spike Raster Plot" #:subtitle "Pre vs Post stimulus"))) (ggsave p "raster.png" #:width 800 #:height 600)
Logarithmic axes
(import gg-plot gg-backend-cairo) (define data '((concentration . (0.1 1 10 100 1000)) (response . (2.1 8.5 42.3 201.7 987.2)))) (define p (ggplot data (aes #:x 'concentration #:y 'response) (layer-point #:size 6 #:color "coral") (layer-line #:width 2 #:color "coral") (scale-x-log #:name "Concentration (uM)" #:base 10) (scale-y-log #:name "Response (% baseline)" #:base 10) (theme-minimal #:base-size 12) (labs #:title "Dose-Response Curve" #:subtitle "Log-log axes"))) (ggsave p "logscale.png" #:width 700 #:height 600)
Faceted plot (small multiples)
(import gg-plot gg-backend-cairo) (define data '((time . (0 10 20 30 0 10 20 30 0 10 20 30)) (power . (8 12 15 11 5 9 14 10 12 18 22 17)) (band . ("Alpha" "Alpha" "Alpha" "Alpha" "Beta" "Beta" "Beta" "Beta" "Gamma" "Gamma" "Gamma" "Gamma")))) (define p (ggplot data (aes #:x 'time #:y 'power) (layer-line #:color "steelblue" #:width 2) (layer-point #:size 4 #:color "darkblue") (facet-wrap 'band #:ncol 3 #:scales "free_y") (scale-x-continuous #:name "Time (s)") (scale-y-continuous #:name "Power (dB)") (theme-bw #:base-size 10) (labs #:title "Power Across Frequency Bands"))) (ggsave p "faceted.png" #:width 1200 #:height 400)
Multiple output formats
(import gg-plot gg-backend-cairo) (define p (ggplot data (aes #:x 'x #:y 'y) (layer-point #:size 6) (theme-minimal) (labs #:title "Multi-format"))) ;; PNG raster (ggsave p "out.png" #:width 600 #:height 400) ;; High-resolution PNG (larger pixel dimensions) (ggsave p "out-hires.png" #:width 2400 #:height 1600) ;; SVG vector (ggsave p "out.svg" #:width 600 #:height 400) ;; PostScript (ggsave p "out.ps" #:width 600 #:height 400) ;; PDF (A4 portrait, dimensions in points) (render-plot p (make-cairo-pdf-backend "out.pdf" 595 842))
Plot specification serialisation
(import gg-plot gg-backend-cairo) (define p (ggplot data (aes #:x 'x #:y 'y) (layer-point #:size 6) (scale-x-continuous #:name "X") (scale-y-continuous #:name "Y") (theme-classic) (labs #:title "Saved plot"))) ;; Serialise to an s-expression and write to disk (define spec (plot->sexp p)) (with-output-to-file "my-plot.scm" (lambda () (write spec) (newline))) ;; Later: load and re-render (define restored (sexp->plot (with-input-from-file "my-plot.scm" read))) (ggsave restored "restored.png" #:width 700 #:height 500)
Programmatic plot generation
;; Build a plot that layers one line per variable (define (multi-line-plot data vars) (apply ggplot data (aes #:x 'time) (append (map (lambda (var) (layer-line #:mapping (aes #:y var) #:width 2)) vars) (list (scale-x-continuous #:name "Time (s)") (scale-y-continuous #:name "Value") (theme-minimal) (labs #:title (format "Variables: ~a" vars))))))
Architecture notes
Scale training
Scales are mutable: scale-train! extends the domain and scale-map reflects the updated domain. The plot pipeline trains each scale by scanning all layers before any geometry is rendered, which allows automatic axis limits that span the full data range across layers.
Drawer composition model
All rendering is expressed as composable drawer values (drawer?). The pipeline builds one large combined drawer per panel and then executes it in a single pass over the plotter.
Author
Repository
https://github.com/iraikov/chicken-ggplot
Version History
- 1.0
- Initial release
License
LPGL-3
References
- Wilkinson, Leland. The grammar of graphics. Springer Science & Business Media, 2005.
- The R ggplot2 package is described in the manuscript, "A layered grammar of graphics", by Hadley Wickham in the Journal of Computational and Graphical Statistics, 2010.