packages feed

hgg (empty) → 0.1.0.0

raw patch · 5 files changed

+370/−0 lines, 5 filesdep +basedep +hgg-3ddep +hgg-core

Dependencies added: base, hgg-3d, hgg-core, hgg-frame, hgg-latex, hgg-pdf, hgg-rasterific, hgg-svg

Files

+ CHANGELOG.md view
@@ -0,0 +1,13 @@+# Changelog for `hgg`++## 0.1.0.0 — 2026-07-19++First public release on Hackage.++- Umbrella package: depends on `hgg-core` / `hgg-frame` / `hgg-svg`+  (exact-pinned) and exposes the single module `Graphics.Hgg`, a thin+  re-export of the Easy API (`Graphics.Hgg.Quick` / `Easy` / `Spec`),+  the dataframe binding (`Graphics.Hgg.Frame`), SVG save+  (`Graphics.Hgg.Backend.SVG`) and units (`Graphics.Hgg.Unit`).+- Manual cabal flags `pdf` / `png` / `latex` / `3d` pull in the optional+  backend packages (`hgg-pdf` / `hgg-rasterific` / `hgg-latex` / `hgg-3d`).
+ LICENSE view
@@ -0,0 +1,30 @@+BSD 3-Clause License++Copyright (c) 2026, Toshiaki Honda+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice,+   this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+   this list of conditions and the following disclaimer in the documentation+   and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its+   contributors may be used to endorse or promote products derived from this+   software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,203 @@+# 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).
+ hgg.cabal view
@@ -0,0 +1,79 @@+cabal-version:      3.0+name:               hgg+version:            0.1.0.0+extra-doc-files:    CHANGELOG.md+                    README.md+synopsis:           A grammar of graphics plotting library for Haskell+description:+  The batteries-included entry point for hgg, a Haskell-native declarative+  plotting library in the grammar-of-graphics tradition (ggplot2 /+  Vega-Lite). Plots are built by monoid composition and can be bound to+  dataframes by column name.+  .+  Depending on this package brings in the core (@hgg-core@), the dataframe+  binding (@hgg-frame@) and the SVG backend (@hgg-svg@), and exposes a+  single module "Graphics.Hgg" — one @import Graphics.Hgg@ gives you the+  Easy API, the full grammar API, the @df |>> spec@ binding and SVG save+  functions.+  .+  > import Graphics.Hgg+  >+  > main :: IO ()+  > main = quickScatter "scatter.svg" [1,2,3,4,5] [1,4,9,16,25]+  .+  Optional backends are pulled in via manual cabal flags: @pdf@+  (@hgg-pdf@), @png@ (@hgg-rasterific@), @latex@ (@hgg-latex@), @3d@+  (@hgg-3d@). Their modules (e.g. "Graphics.Hgg.Backend.PDF") are imported+  from the backend packages directly. Alternatively, depend on the backend+  packages themselves — this umbrella is a convenience, not a requirement.+license:            BSD-3-Clause+homepage:           https://github.com/frenzieddoll/hgg+license-file:       LICENSE+author:             Toshiaki Honda+maintainer:         frenzieddoll@gmail.com+copyright:          2026 Aelysce Project (Toshiaki Honda)+category:           Graphics+build-type:         Simple++flag pdf+  description: Pull in the PDF backend (hgg-pdf, needs a LaTeX engine at runtime)+  manual:      True+  default:     False++flag png+  description: Pull in the PNG backend (hgg-rasterific)+  manual:      True+  default:     False++flag latex+  description: Pull in the LaTeX (TikZ) backend (hgg-latex)+  manual:      True+  default:     False++flag 3d+  description: Pull in 3D plotting (hgg-3d)+  manual:      True+  default:     False++common warnings+  ghc-options:        -Wall -Wcompat -Widentities -Wincomplete-record-updates+                      -Wincomplete-uni-patterns -Wpartial-fields+                      -Wredundant-constraints++library+  import:           warnings+  exposed-modules:  Graphics.Hgg+  hs-source-dirs:   src+  build-depends:    base       >= 4.17 && < 5+                  , hgg-core  == 0.1.0.0+                  , hgg-frame == 0.1.0.0+                  , hgg-svg   == 0.1.0.0+  if flag(pdf)+    build-depends:  hgg-pdf == 0.1.0.0+  if flag(png)+    build-depends:  hgg-rasterific == 0.1.0.0+  if flag(latex)+    build-depends:  hgg-latex == 0.1.0.0+  if flag(3d)+    build-depends:  hgg-3d == 0.1.0.0+  default-language: Haskell2010
+ src/Graphics/Hgg.hs view
@@ -0,0 +1,45 @@+-- |+-- Module      : Graphics.Hgg+-- Description : Batteries-included entry point (Easy API + grammar + df binding + SVG save)+-- Copyright   : (c) 2026 Aelysce Project (Toshiaki Honda)+-- License     : BSD-3-Clause+--+-- One import for the whole default experience:+--+-- @+-- import Graphics.Hgg+--+-- main :: IO ()+-- main = quickScatter "scatter.svg" [1,2,3,4,5] [1,4,9,16,25]+-- @+--+-- Re-exports, thinnest to richest:+--+-- * "Graphics.Hgg.Quick" — one-line IO save helpers ('quickScatter',+--   'quickPlot', …), which itself re-exports the Easy API+--   ("Graphics.Hgg.Easy": 'points', 'overlay', …) and the full grammar API+--   ("Graphics.Hgg.Spec": 'scatter', 'layer', 'title', …).+-- * "Graphics.Hgg.Frame" — the @df '|>>' spec@ binding ('PlotData',+--   'BoundPlot').+-- * "Graphics.Hgg.Backend.SVG" — 'saveSVG', 'saveSVGBound' and friends.+-- * "Graphics.Hgg.Unit" — physical lengths ('px', 'mm', '*~') for+--   'widthUnit' \/ 'heightUnit' and friends.+--+-- Other backends (PDF \/ PNG \/ LaTeX \/ 3D) are not re-exported here;+-- enable them with the package's manual cabal flags (@pdf@ \/ @png@ \/+-- @latex@ \/ @3d@) and import e.g. "Graphics.Hgg.Backend.PDF" directly.+module Graphics.Hgg+  ( -- * Easy API + grammar (via Quick)+    module Graphics.Hgg.Quick+    -- * DataFrame binding+  , module Graphics.Hgg.Frame+    -- * SVG output+  , module Graphics.Hgg.Backend.SVG+    -- * Units+  , module Graphics.Hgg.Unit+  ) where++import           Graphics.Hgg.Backend.SVG+import           Graphics.Hgg.Frame+import           Graphics.Hgg.Quick+import           Graphics.Hgg.Unit