Skip to content

nathan-ed/typst-package-simple-plot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simple-plot

A simple, pgfplots-like function plotting library for Typst. Create beautiful mathematical plots with minimal code.

Note: This package is built on top of CeTZ v0.4.2.

Manual

A full manual is available in docs/manual.pdf.

Gallery

Click on an image to see the source code.

Parabola plot with labeled vertex and roots Trigonometric functions sin and cos with grid Scatter plot with data points
Parabola Trigonometric Functions Scatter Plot
Exponential and logarithmic function plots Data points with polynomial model fit curve Available marker types: circle, square, triangle, diamond
Exponential & Logarithmic Data with Model Fit Marker Types
Extended axes with custom tick labels and unit Area fills, hatching, and Riemann sum overlays 3D-style volume of revolution with disk cross-sections
Extended Axes Area Fills & Riemann Sums Volume of Revolution
All five Riemann sum methods with annotation features
Riemann Sum Features

Features

  • Simple API — Plot functions with just a few lines of code
  • Multiple plot types — Functions, scatter plots, line plots with markers
  • Customizable axes — Position, labels, ticks, and tick labels; default $x$/$y$ labels at arrow tips (tkz-fct style)
  • Stealth arrows — Elegant axis arrowheads matching LaTeX/pgfplots style
  • Axis extension — Extend axes beyond plot area for cleaner appearance
  • Grid support — Major and minor grids with custom styling
  • 14 marker types — Circles, squares, triangles, diamonds, stars, and more
  • Origin label control — Toggle origin '0' label display
  • Global defaults — Set defaults for all plots in your document
  • Riemann sums — Left/right/midpoint/lower/upper rectangles; endpoint dots with labels and arrows; Δx bracket; $x_i$ subdivision labels
  • Volume of revolution — 3D-style solids: arbitrary axis (horizontal, shifted, or oblique), end caps, disk cross-sections, optional coordinate axes
  • Full styling — Customize colors, strokes, backgrounds, and more

Quick Start

#import "@local/simple-plot:0.8.0": plot

#plot(
  xmin: -3, xmax: 3,
  ymin: -1, ymax: 9,
  show-grid: true,
  (fn: x => calc.pow(x, 2), stroke: blue + 1.5pt),
)

Axis labels default to $x$ and $y$ — no need to set them explicitly.

Basic Usage

Plotting Functions

#import "@local/simple-plot:0.8.0": plot

// Single function
#plot(
  xmin: -5, xmax: 5,
  ymin: -5, ymax: 5,
  show-grid: "major",
  (fn: x => calc.sin(x), stroke: blue + 1.5pt),
)

// Multiple functions
#plot(
  xmin: -2 * calc.pi, xmax: 2 * calc.pi,
  ymin: -1.5, ymax: 1.5,
  (fn: x => calc.sin(x), stroke: blue + 1.2pt, label: $sin(x)$),
  (fn: x => calc.cos(x), stroke: red + 1.2pt, label: $cos(x)$),
)

Scatter Plots

#import "@local/simple-plot:0.8.0": plot, scatter

#plot(
  xmin: 0, xmax: 10,
  ymin: 0, ymax: 10,
  show-grid: true,
  scatter(
    ((1, 2), (2, 3.5), (3, 2.8), (4, 5.2), (5, 4.8)),
    mark: "*",
    mark-fill: blue,
  ),
)

Line Plots with Markers

#import "@local/simple-plot:0.8.0": plot, line-plot

#plot(
  xmin: 0, xmax: 10,
  ymin: 0, ymax: 12,
  axis-x-pos: "bottom",
  axis-y-pos: "left",
  line-plot(
    ((0, 0), (1, 0.5), (2, 1.8), (3, 4.2), (4, 5.1)),
    stroke: blue + 1.2pt,
    mark: "*",
    mark-fill: blue,
  ),
)

Function Labels with Positioning

Control the placement of function labels using label-pos and label-side:

#plot(
  xmin: -5, xmax: 5,
  ymin: -3, ymax: 5,
  show-grid: true,
  (fn: x => 0.2 * calc.pow(x, 2) - 2,
   stroke: blue + 1.5pt,
   label: $f(x)$,
   label-pos: 0.9,           // position along curve (0–1)
   label-side: "below-right" // placement relative to point
  ),
  (fn: x => -0.5 * x + 1,
   stroke: red + 1.5pt,
   label: $g(x)$,
   label-pos: 0.2,
   label-side: "above-right"
  ),
)

Available label-side options: "above", "below", "left", "right", "above-left", "above-right", "below-left", "below-right"

Mathematical Functions

Function Typst syntax
Power $x^n$ calc.pow(x, n)
Square root calc.sqrt(x)
Absolute value calc.abs(x)
Sine, Cosine, Tangent calc.sin(x), calc.cos(x), calc.tan(x)
Exponential $e^x$ calc.exp(x)
Natural log calc.ln(x)
Log base b calc.log(x, base: b)

Important: Use decimal notation (e.g. 2.0 not 2) inside lambda functions to avoid type errors.

Parameters Reference

Plot Parameters

Parameter Type Default Description
xmin, xmax float -5, 5 X-axis range
ymin, ymax float -5, 5 Y-axis range
width, height float 6, 6 Plot size in cm
scale float 1 Scale factor for the entire plot
xlabel, ylabel content $x$, $y$ Axis labels (default: tkz-fct style at arrow tips)
show-grid bool/str false true, false, "major", "minor", "both"
minor-grid-step int 5 Minor grid subdivisions per major tick
grid-label-break bool true Gap in grid lines around tick labels
axis-x-pos float/str 0 X-axis position: value, "bottom", "center"
axis-y-pos float/str 0 Y-axis position: value, "left", "center"
axis-x-extend float/array (0, 0.5) Extend X-axis beyond grid: value or (left, right)
axis-y-extend float/array (0, 0.5) Extend Y-axis beyond grid: value or (bottom, top)
show-origin bool true Show "0" label at origin
unit-label-only bool false Show only "1" on axes for minimal style

Axis Label Placement

Labels default to tkz-fct style: $x$ sits below-right of the arrowhead, $y$ sits to the left.

Parameter Type Default Description
xlabel-pos str/array "end" "end", "center", or (x, y) in data coords
ylabel-pos str/array "end" same
xlabel-anchor str "north-west" CeTZ anchor — top-left of text at position
ylabel-anchor str "east" CeTZ anchor — right edge of text at position
xlabel-offset array (0.0, -0.03) Offset (x, y) in cm from arrow tip
ylabel-offset array (-0.05, 0.0) Offset (x, y) in cm from arrow tip

Tick Configuration

Parameter Type Default Description
xtick, ytick auto/none/array auto Tick positions
xtick-step, ytick-step auto/float 1 Step between ticks
xtick-label-step, ytick-label-step int 1 Show label every N ticks
xtick-labels, ytick-labels auto/array auto Custom tick labels

Function Specification

(
  fn: x => ...,           // Required: the function
  stroke: blue + 1.2pt,   // Line style
  domain: (min, max),     // Restrict domain
  samples: 100,           // Sample points
  label: $f(x)$,          // Label content
  label-pos: 0.8,         // Position along curve (0–1)
  label-side: "above",    // "above", "below", "left", "right", "above-left", …
  mark: "o",              // Marker type
  mark-size: 0.1,
  mark-fill: white,
  mark-stroke: blue,
  mark-interval: 10,      // Show marker every N points
)

Riemann Sums

#import "@local/simple-plot:0.8.0": plot, riemann-sum

#plot(
  xmin: 0, xmax: 3, ymin: 0, ymax: 5,
  riemann-sum(
    x => calc.pow(x, 2),
    domain: (0.0, 3.0),
    n: 6,
    method: "left",
    color: blue.lighten(75%),
    show-points: true,       // dots at evaluation points with arrows
    show-dx: true,           // Δx bracket under one rectangle
    show-xi: true,           // x₀, x₁, …, x₆ labels along axis
  ),
  (fn: x => calc.pow(x, 2), stroke: blue + 1.5pt),
)

riemann-sum Parameters

Parameter Type Default Description
fn function Function to integrate
domain array plot range (a, b)
n int 4 Number of rectangles
method str "right" "left", "right", "mid", "lower", "upper"
baseline float 0 Y-level of rectangle bases
color color luma(220) Rectangle fill
stroke stroke luma(80) + 0.6pt Rectangle border
hatch str/none none Hatch pattern: "ne", "nw", "h", "v", "cross", "grid"
hatch-spacing length 5pt Spacing between hatch lines
hatch-stroke stroke luma(80) + 0.5pt Stroke for hatch lines
samples int 20 Samples per subinterval for "lower"/"upper"
show-points bool false Draw dot at each evaluation point
point-color color rgb("#c94a00") Dot fill color
point-size float 0.07 Dot radius in cm
point-label content/auto/none auto Label with arrows to dots; auto = method name
point-label-pos array/auto auto (x, y) in data coords; auto = upper-right of dots
show-dx bool false Draw Δx dimension bracket under one rectangle
dx-rect int/auto auto Rectangle index to annotate (0-based); auto = middle
dx-label content $Delta x$ Bracket label
show-xi bool false Draw $x_0, x_1, \ldots, x_n$ at subdivision points
xi-labels array/auto auto Custom labels array; auto = subscripted $x_i$
xi-show-values bool false Show numeric x-values instead of $x_i$ notation

Methods:

  • "left" / "right" / "mid" — evaluation at left endpoint, right endpoint, or midpoint
  • "lower" / "upper" — true infimum/supremum (sampled within each subinterval); works for any function shape including U-curves

Volume of Revolution

#import "@local/simple-plot:0.8.0": volume-of-revolution

#volume-of-revolution(
  x => calc.sqrt(x),
  domain: (0.0, 4.0),
  n-disks: 5,
  width: 8.0,
  height: 4.0,
  show-yaxis: true,
  label-a: $0$,
  label-b: $4$,
  label-f: $f(x)=sqrt(x)$,
)

solid-of-revolution is an alias for backward compatibility.

volume-of-revolution Parameters

Parameter Type Default Description
fn function Profile function $y = f(x) > 0$
domain array (0, 4) (a, b) — interval of revolution
n-disks int 4 Intermediate disk cross-sections to show
width, height float 5, 3.5 Canvas size in cm
samples int 60 Profile sampling points
axis-y float 0 Y-value of revolution axis (default: x-axis)
axis-slope float 0 Slope $m$ of revolution axis: $y = mx + \text{axis_y}$
show-axis bool true Draw the revolution axis arrow
show-yaxis bool false Draw a coordinate y-axis (show-y-axis is the canonical spelling)
y-axis-x / yaxis-x auto/float auto X position for the y-axis; auto = left of volume
y-axis-offset float 0.45 Gap between the y-axis and the volume when y-axis-x: auto
y-axis-extend array (0.35, 0.45) Y-axis padding (below, above) the volume
show-radius-marker bool false Draw a vertical radius dimension marker at yaxis-x
show-back bool true Draw the back face and bottom profile
show-labels bool true Show $a$, $b$, $f$ labels
profile-stroke stroke blue + 1.5pt Top profile curve
disk-color color luma(218) Solid body fill
disk-stroke stroke luma(90) + 0.6pt Disk edge stroke
axis-stroke stroke black + 0.7pt Revolution axis stroke
label-a, label-b content $a$, $b$ Domain endpoint labels
label-f content $f$ Function label
label-y content $y$ Y-axis label

Marker Types

Type Description Type Description
"o" Hollow circle "*" Filled circle
"square" Hollow square "square*" Filled square
"triangle" Hollow triangle "triangle*" Filled triangle
"diamond" Hollow diamond "diamond*" Filled diamond
"star" Hollow star "star*" Filled star
"+" Plus sign "x" Cross
`" "` Vertical bar "-"
"none" No marker

Custom Styling

#plot(
  style: (
    axis: (
      stroke: black + 1pt,
      arrow: (symbol: "stealth", fill: black, scale: 0.55),
    ),
    grid: (
      major: (stroke: luma(200) + 0.5pt),
      minor: (stroke: luma(230) + 0.3pt),
    ),
    ticks: (
      length: 0.1,
      stroke: black + 0.6pt,
      label-offset: 0.15,
      label-size: 10pt,
    ),
  ),
  // ...
)

Setting Global Defaults

#import "@local/simple-plot:0.8.0": set-plot-defaults, reset-plot-defaults

#set-plot-defaults(width: 6, height: 4, show-grid: "major")

// All subsequent plots use these defaults
#plot(xmin: -2, xmax: 2, ymin: 0, ymax: 4,
  (fn: x => calc.pow(x, 2)))

#reset-plot-defaults()

Comparison with Other Plotting Libraries

simple-plot is designed for mathematical function plotting with a focus on simplicity and ease of use. Choose simple-plot when you need to:

  • Plot mathematical functions quickly with minimal boilerplate code
  • Create publication-quality plots for math, physics, or engineering documents
  • Use a familiar API similar to pgfplots/matplotlib for straightforward plotting tasks

Alternatives:

  • cetz-plot: Better for business charts and general data visualization (pie, bar, pyramid charts).
  • lilaq: More powerful for complex scientific visualizations (colormesh, contour, quiver) but steeper learning curve.

Dependencies

License

MIT License — see LICENSE file for details.

Changelog

[0.8.0] - 2026-05-21

Added

  • riemann-sum: complete feature documentation — full API table with all 23 parameters: method ("left", "right", "mid", "lower", "upper"), hatch controls (hatch, hatch-spacing, hatch-stroke), annotation flags (show-points, point-color, point-size, point-label, point-label-pos, show-dx, dx-rect, dx-label, show-xi, xi-labels, xi-show-values), and samples
  • volume-of-revolution: complete feature documentation — full API table with all parameters including axis-y, axis-slope, show-y-axis, yaxis-x, y-axis-offset, y-axis-extend, show-radius-marker, show-back, show-labels, label params; solid-of-revolution alias documented
  • Gallery: riemann-features.typ — 8-demo showcase of all Riemann sum features side by side

[0.7.0] - 2026-05-21

Fixed

  • Riemann sum xi-label x-shift on y-axis increased from 0.18 to 0.35 to prevent overlap with axis line

[0.6.0] - 2026-05-21

Added

  • volume-of-revolution — renamed from solid-of-revolution (alias kept); supports arbitrary revolution axis via axis-y and axis-slope; new show-yaxis, show-back, label-y parameters; ellipses rendered via polygon points for smoother output
  • Riemann sum: "lower"/"upper" methods — true infimum/supremum by sampling within each subinterval; works for U-curves and any shape
  • Riemann sum: endpoint dotsshow-points, point-color, point-size, point-label, point-label-pos; draws dots at evaluation points with a text label and stealth arrows
  • Riemann sum: Δx bracketshow-dx, dx-rect, dx-label; dimension bracket with tick marks under a chosen rectangle
  • Riemann sum: subdivision labelsshow-xi, xi-labels; draws $x_0, x_1, \ldots, x_n$ at subdivision points
  • Default axis labelsxlabel and ylabel now default to $x$ and $y$ (tkz-fct style)
  • Axis label placement — new defaults: x below-right of arrowhead ("north-west" anchor), y to the left ("east" anchor); matches standard math textbook style

Fixed

  • Axis arrow style changed from bare "stealth" string (inherited large global scale) to explicit (symbol: "stealth", fill: black, scale: 0.55) — arrows are now elegantly sized
  • Global mark scale removed from canvas set-style to avoid oversizing user-defined marks

[0.3.0] - 2026-02-18

Changed

  • Grid label break: gap-based grid drawing replaces white-box overlay; works on any background color

Fixed

  • Origin label no longer duplicates when show-origin: true and axes cross at origin

[0.2.6] - 2026-02-04

Added

  • Grid label breaks, integer tick defaults, xtick-label-step/ytick-label-step, unit-label-only, axis arrows extending beyond grid

[0.2.5] - 2026-01-27

Fixed

  • label-pos now respects explicit function domains

[0.2.0] - 2026-01-15

Added

  • axis-x-extend, axis-y-extend, show-origin, label-side, Liang-Barsky clipping

[0.1.0] - 2026-01-13

Added

  • Initial release: function plotting, scatter/line plots, 14 marker types, customizable axes, grid, ticks, labels, global defaults

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages