A very simple but useful plots lib for the Odin programming language.
A tiny, dependency-light 2D plotting library written in Odin. It is a bare-minimum software renderer that draws directly into an RGBA pixel buffer and saves the result to disk as PNG or JPG via vendor:stb/image.
No external GUI, no fonts, no SVG, no GPU — everything ( lines, ticks, grid, axes, legend, colour-bar, text ) is drawn by hand into pixels with an embedded 5×7 bitmap font.
- Plot types: line / scatter (
Standard), heatmap with colour-bar (Elevation), andHistogram. - Multiple traces per standard plot with auto-assigned colours from
DEFAULT_PALETTE. - Real axes: nice rounded tick steps, gridlines, four-quadrant support, optional zero-axes through the origin, X / Y axis labels ( Y is rendered vertically) and an automatic textual legend with colour swatches.
- Auto-computed margins from the actual content (title, labels, legend width, plot type) — or override with
set_margins. - Text scaling 1× / 2× / 3× for hi-DPI / 4K monitors (
set_text_scale). - Themes:
Light,Dark, orCustom. - Output: PNG (
save_png) or JPG (save_jpg).
make # odin build . -out:plots_test.exe -o:speed
./plots_test.exeThis produces the four images shown below.
package main
import plt "plots_bare_minimum"
main :: proc( ) {
plot, _ := plt.create_plot( 1280, 800, .Light )
defer plt.destroy_plot( & plot )
plt.set_title( & plot, "sin(x)" )
plt.set_axis_labels( & plot, "x", "y" )
xs := plt.linearspace( -6.28, 6.28, 400 )
defer delete( xs )
ys := make( [ ]f64, len( xs ) )
defer delete( ys )
for x, i in xs do ys[ i ] = math.sin( x )
plt.add_trace_auto( & plot, "sin", xs, ys, .Line )
plt.save_png( & plot, "sin.png" )
}| Name | Description |
|---|---|
Plot |
The plot state (canvas, traces, margins, theme, ...). |
Plot_Error |
Error enum returned by most procs. |
Theme_Mode |
.Light, .Dark, .Custom. |
Theme |
Colour set used by a plot (background, axis, grid, text, …). |
Color |
[4]u8 — RGBA. |
Marker_Type |
.Line, .Dot, .Cross, .Both. |
Plot_Type |
.Standard, .Elevation, .Histogram (set automatically). |
DEFAULT_PALETTE |
Built-in colour cycle used by add_trace_auto. |
| Proc | Description |
|---|---|
create_plot( width, height, mode := .Dark ) -> ( Plot, Plot_Error ) |
Allocate a new plot canvas. |
destroy_plot( plot: ^Plot ) |
Free the plot and any owned data ( histogram bins, etc. ). |
| Proc | Description |
|---|---|
set_title( plot, title ) |
Plot title (drawn at fixed text scale 2). |
set_axis_labels( plot, x_label, y_label ) |
Axis legends; Y label is rendered vertically. |
set_x_range( plot, min_x, max_x ) |
Manual X range ( otherwise auto-scaled from data ). |
set_y_range( plot, min_y, max_y ) |
Manual Y range. |
set_margins( plot, left, right, top, bottom ) |
Manual margins ( disables auto-margins ). |
set_text_scale( plot, scale ) |
Text size for ticks/labels/legend: 1, 2 or 3 ( clamped ). Title stays at 2. |
set_show_grid( plot, on ) |
Show/hide the grid lines. |
set_show_legend( plot, on ) |
Show/hide the legend box. |
set_show_zero_axes( plot, on ) |
Show/hide the X=0 / Y=0 axes through the origin. |
| Proc | Description |
|---|---|
linearspace( start, stop, n ) -> []f64 |
NumPy-style evenly spaced points ( caller owns the slice ). |
add_trace( plot, name, x, y, color, marker := .Line ) -> Plot_Error |
Add a trace with an explicit colour. |
add_trace_auto( plot, name, x, y, marker := .Line ) -> Plot_Error |
Add a trace and pick the next palette colour. |
add_histogram( plot, name, data, num_bins, color ) -> Plot_Error |
Compute bins and add a histogram ( honours set_x_range ). |
add_elevation( plot, z_data, grid_w, grid_h ) -> Plot_Error |
Heatmap data, row-major grid_w * grid_h values. |
| Proc | Description |
|---|---|
save_png( plot, filename ) -> Plot_Error |
Render and write a PNG. |
save_jpg( plot, filename , quality := 90 ) -> Plot_Error |
Render and write a JPG. |
.
├── main.odin # Demos that produce the 4 images above
├── plots_bare_minimum/
│ └── plots_bare_minimum.odin # The library
├── Makefile # `make`, `make run`, `make clean`
└── README.md
MIT open source license
Best regards,
Joao Carvalho



