hugin
matplotlib's flexibility. OCaml's elegance. publication-ready plots.
why hugin?
beautiful by default
Publication-quality output without endless tweaking. Sensible defaults that just work.
functional composition
Build complex visualizations by composing simple elements. No hidden global state.
type-safe plotting
Mismatched dimensions? Wrong data type? The compiler catches it before you waste time.
cairo + SDL backends
Interactive windows for exploration. PNG export for sharing. Same API for both.
show me the code
MATPLOTLIB
import matplotlib.pyplot as plt import numpy as np # Create data x = np.linspace(0, 10, 100) y = np.sin(x) # Plot plt.figure(figsize=(8, 6)) plt.plot(x, y, color='blue') plt.xlabel('x') plt.ylabel('sin(x)') plt.grid(True) plt.show()
HUGIN
open Hugin open Nx (* Create data *) let x = linspace float32 0. 10. 100 let y = Nx.map Float.sin x (* Plot *) let () = let fig = figure ~width:800 ~height:600 () in let ax = subplot fig in let _ = ax |> Plotting.plot ~x ~y ~color:Artist.Color.blue |> Axes.set_xlabel "x" |> Axes.set_ylabel "sin(x)" |> Axes.grid true in show fig
functional style
Hugin embraces OCaml's pipeline operator. Build plots by transforming axes:
let plot_data ax = ax |> Plotting.plot ~x ~y1 ~label:"sin" ~color:Artist.Color.red |> Plotting.plot ~x ~y2 ~label:"cos" ~color:Artist.Color.blue |> Axes.set_title "Trigonometric Functions" |> Axes.set_xlim ~min:0. ~max:10.
what works today
2D plotting
(* Lines and scatter *) Plotting.plot ~x ~y Plotting.scatter ~x ~y (* Bar charts *) Plotting.bar ~x ~heights (* Histograms *) Plotting.hist ~values ~bins:30
styling
(* Colors *) Artist.Color.red Artist.Color.rgba 0.5 0.5 0.5 1.0 (* Line styles *) Artist.Solid Artist.Dashed (* Markers *) Artist.Circle Artist.Square
display images
(* Load and display *) let img = Nx_io.load_image "photo.jpg" in let fig = imshow ~title:"My Image" img in show fig
get started
Hugin needs Cairo and SDL2. Install them first:
# macOS brew install cairo sdl2 # Ubuntu apt install libcairo2-dev libsdl2-dev
Hugin isn't released yet. For now, check out the documentation to learn more.
When it's ready:
# Install opam install hugin # Try it open Hugin open Nx let () = let x = linspace float32 0. (2. *. Float.pi) 100 in let y = Nx.map Float.sin x in let fig = figure () in let _ = subplot fig |> Plotting.plot ~x ~y in savefig fig "plot.png"