packages feed

hgg-0.1.0.0: README.md

# hgg — a grammar of graphics for Haskell

A Haskell-native declarative plotting library. Like ggplot2 and Vega-Lite it
follows the **grammar of graphics** philosophy: plots are built by **monoid
composition** — `purePlot <> layer (mark …) <> settings …`. It pairs with the
statistical library [**hanalyze**](https://hackage.haskell.org/package/hanalyze)
(hanalyze = analysis / hgg = visualization), so fitted models — regression, GLM,
GP, survival, time series, Bayesian HBM — can be overlaid directly onto plots.

> **Status**: practical, pre-1.0 (API stabilising). SVG / PDF / PNG / Jupyter backends work today.

This is the **umbrella package**: depending on `hgg` brings in the core
(`hgg-core`), the dataframe binding (`hgg-frame`) and the SVG backend
(`hgg-svg`), and a single `import Graphics.Hgg` covers the whole default
experience.

<img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/tutorials/01-visualize/09-final.svg" width="560" alt="Finished plot: penguin body mass vs flipper length, coloured and shaped by species, with a regression line">

## Gallery

<table>
  <tr>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L94"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/line.svg" width="210" alt="function lines"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L102"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/scatter.svg" width="210" alt="scatter"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L107"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/histogram.svg" width="210" alt="histogram"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L112"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/density.svg" width="210" alt="density"></a></td>
  </tr>
  <tr>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L124"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/boxplot.svg" width="210" alt="boxplot"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L129"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/violin.svg" width="210" alt="violin"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L151"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/contour.svg" width="210" alt="contour"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L156"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/heatmap.svg" width="210" alt="heatmap"></a></td>
  </tr>
  <tr>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L215"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/hexbin.svg" width="210" alt="hexbin"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L167"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/quiver.svg" width="210" alt="vector field"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L177"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/bar.svg" width="210" alt="stacked bar"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L182"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/pie.svg" width="210" alt="pie chart"></a></td>
  </tr>
  <tr>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/api-guide/04-decoration.md#facet"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/tutorials/01-visualize/24-facet-island.svg" width="210" alt="facets"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L139"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/distcols.svg" width="210" alt="distCols side-by-side"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L188"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/subplots.svg" width="210" alt="subplots patchwork"></a></td>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L204"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/surface3d.svg" width="210" alt="3D response surface"></a></td>
  </tr>
  <tr>
    <td><a href="https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs#L226"><img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/hbm-hier-dag.svg" width="210" alt="hierarchical Bayesian model DAG"></a></td>
  </tr>
</table>

Click any figure to jump to its **generating code**
([`hgg-tutorials/readme-images/ReadmeImages.hs`](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/hgg-tutorials/readme-images/ReadmeImages.hs));
the facet figure comes from the
[R4DS tutorial](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/tutorials/01-visualize/README.md).
The full API reference lives in the
[api-guide](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/api-guide/02-layers.md).
All 24 penguins figures with reproduction code are in
[R for Data Science, chapter 1](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/tutorials/01-visualize/README.md).

## Installation

Add `hgg` to your `build-depends`:

```
build-depends: hgg
```

Optional backends are enabled with manual cabal flags — in your
`cabal.project`:

```
constraints: hgg +pdf +png +latex +3d
```

| Flag | Pulls in | Gives you |
|---|---|---|
| `pdf` | `hgg-pdf` | PDF output (`Graphics.Hgg.Backend.PDF`) |
| `png` | `hgg-rasterific` | PNG output, Japanese fonts supported (`Graphics.Hgg.Backend.Rasterific`) |
| `latex` | `hgg-latex` | LaTeX/TikZ output (`Graphics.Hgg.Backend.LaTeX`) |
| `3d` | `hgg-3d` | 3D plots, CPU projection (`Graphics.Hgg.ThreeD`) |

The umbrella is a convenience, not a requirement: you can instead depend on
the individual packages (`hgg-svg`, `hgg-pdf`, `hgg-rasterific`, `hgg-latex`,
`hgg-3d`, `hgg-ihaskell`, `hgg-custom`, `hgg-analyze-bridge`) and skip `hgg`
entirely — for Jupyter inline display use `hgg-ihaskell`.

## Quick start

The shortest form is one line (one figure, no decisions beyond the data).

```haskell
import Graphics.Hgg

main :: IO ()
main = quickScatter "scatter.svg" [1,2,3,4,5] [1,4,9,16,25]
```

To add decorations, use the Easy helpers (direct values + `overlay`).

```haskell
import Graphics.Hgg

main :: IO ()
main = saveSVG "easy.svg" $
     overlay [ points [1,2,3,4,5] [1,4,9,16,25] ]
  <> title "y = x²" <> xLabel "x" <> yLabel "y"
  <> widthUnit (600 *~ px) <> heightUnit (400 *~ px)
```

To work with **column names**, bind a data source with `|>>` (the idiomatic
style). Put a value that has columns on the left of `|>>` (below: inline
`[(name, ColData)]`) and refer to columns by name in the spec on the right.
`|>>` binds more loosely than `<>`, so no outer parentheses are needed even
with several layers.

```haskell
import Graphics.Hgg
import qualified Data.Vector as V
import Data.Text (Text)

main :: IO ()
main = saveSVGBound "bound.svg" $
     cols |>> layer (scatter "x" "y")
  <> title "y = x²" <> xLabel "x" <> yLabel "y"
  where
    cols = [ ("x", NumData (V.fromList [1,2,3,4,5]))
           , ("y", NumData (V.fromList [1,4,9,16,25])) ] :: [(Text, ColData)]
```

<img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/images/readme/quickstart.svg" width="420" alt="scatter plot of y = x²">

## A taste of the grammar

A plot is the empty `purePlot` plus `layer (mark …)` pieces combined with `<>`.
Data is bound with `|>>`; colour and shape are given inside the mark with
`colorBy`/`shapeBy` (below, `raw` is palmerpenguins).

**1. Scatter** — a `scatter` mark with column names produces axes and points.

```haskell
saveSVGBound "04-scatter.svg" $
  raw |>> layer (scatter "flipper_length_mm" "body_mass_g" <> alpha 0.85)
      <> xLabel "flipper_length_mm" <> yLabel "body_mass_g"
      <> theme ThemeGrey
```

<img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/tutorials/01-visualize/04-scatter.svg" width="420" alt="scatter plot">

**2. Colour by species** — add `colorBy "species"` to the mark.

```haskell
saveSVGBound "05-color.svg" $
  raw |>> layer (scatter "flipper_length_mm" "body_mass_g"
                 <> colorBy "species" <> alpha 0.85)
      <> xLabel "flipper_length_mm" <> yLabel "body_mass_g"
      <> legendTitle "species"
      <> theme ThemeGrey
```

<img src="https://raw.githubusercontent.com/frenzieddoll/hgg/v0.1.0.0/docs/tutorials/01-visualize/05-color.svg" width="420" alt="coloured scatter plot">

**3. Overlay a regression line and labels** — keep adding layers and decorations with `<>`.

```haskell
saveSVGBoundStats "09-final.svg" $
  raw |>> layer (scatter "flipper_length_mm" "body_mass_g"
                 <> colorBy "species" <> shapeBy "species" <> alpha 0.85)
      <> layer (statLm "flipper_length_mm" "body_mass_g" <> color smoothBlue)
      <> palette okabeIto
      <> title "Body mass and flipper length"
      <> subtitle "Dimensions for Adelie, Chinstrap, and Gentoo Penguins"
      <> xLabel "Flipper length (mm)" <> yLabel "Body mass (g)"
      <> legendTitle "Species"
      <> theme ThemeGrey
```

The full step-by-step walkthrough is in the
[R for Data Science, chapter 1 tutorial](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/tutorials/01-visualize/README.md).

## What you can do

- **Layer/mark declarative API** — scatter, line, bar, histogram, boxplot, violin,
  density, band, forest, heatmap, contour, vector field, DAG, MCMC diagnostics, …
- **DataFrame integration** — write `df |>> layer (scatter "x" "y")` with column names
  (NA rows are dropped automatically, i.e. `na.rm`)
- **Backends** — SVG / PDF / PNG (Japanese fonts supported) / LaTeX (TikZ) / Jupyter (iHaskell) inline
- **3D** — response surfaces (RSM) and generic 3D plots (CPU projection)
- **Statistical integration** — `toPlot` / `statLm` / HBM extractors draw
  hanalyze's fitted models directly
- **Full decoration set** — themes / scales / facets / subplots / coordinate systems /
  reference lines / legends (ggplot-alike)

## Documentation

- [Gallery + full README](https://github.com/frenzieddoll/hgg#readme)
- [API Reference](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/api-guide/README.md) — organised by topic
- [Tutorial: R for Data Science, chapter 1](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/tutorials/01-visualize/README.md)
- [Getting Started](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/getting-started.md) /
  [ggplot2 Migration Guide](https://github.com/frenzieddoll/hgg/blob/v0.1.0.0/docs/migration-from-ggplot.md)

## License

BSD-3-Clause (same as hanalyze).