diff --git a/app/scatter/Main.hs b/app/scatter/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/scatter/Main.hs
@@ -0,0 +1,47 @@
+module Main where
+
+import Control.Monad (forM_)
+
+import qualified Data.Colour as C
+import qualified Data.Colour.Names as C
+import Data.Scientific (Scientific, toRealFloat)
+import qualified Data.Text as T 
+import qualified Data.Text.IO as T (readFile, writeFile)
+import Text.Blaze.Svg.Renderer.String (renderSvg)
+
+import Graphics.Rendering.Plot.Light
+import Graphics.Rendering.Plot.Light.PlotTypes
+
+xPlot = 400
+yPlot = 300
+fnameOut = "data/scatter-1.svg"
+
+fdat = FigureData xPlot yPlot 0.1 0.8 0.1 0.9 10
+
+dats = zipWith LabeledPoint p_ l_ where
+  l_ = [-5, -4 .. ]
+  p_ = zipWith Point [4,7,12,23,90,34,24,5,6,12,3] [43,23,1,23,8,11,17,25,4,5]
+
+spdata = ScatterPointData Circle 3 3 C.red
+
+
+main = do
+  let
+    frameTo = frameFromFigData fdat
+    frameFrom = frameFromPoints $ _lp <$> dats
+    vmin = minimum $ _lplabel <$> dats
+    vmax = maximum $ _lplabel <$> dats     
+    f l sz = 10/(1 + exp(-(0.3 * x)))
+      where x = l + sz
+    g _ w = w
+    h l col = C.blend l' C.blue col
+      where
+        l' = (l - vmin)/(vmax - vmin)
+    dats' = moveLabeledPointBwFrames frameFrom frameTo False True <$> dats
+    svg_t = svgHeader xPlot yPlot $ do
+      axes fdat frameFrom 2 C.black 10 10
+      scatterLP f g h spdata dats'
+      scatterLPBar fdat 50 vmin vmax 3 TopRight 100 f g h spdata
+  -- putStrLn $ renderSvg svg_t
+  T.writeFile fnameOut $ T.pack $ renderSvg svg_t
+    
diff --git a/doc/fig/heatmap.png b/doc/fig/heatmap.png
Binary files a/doc/fig/heatmap.png and b/doc/fig/heatmap.png differ
diff --git a/doc/fig/scatter.png b/doc/fig/scatter.png
new file mode 100644
Binary files /dev/null and b/doc/fig/scatter.png differ
diff --git a/plot-light.cabal b/plot-light.cabal
--- a/plot-light.cabal
+++ b/plot-light.cabal
@@ -1,5 +1,5 @@
 name:                plot-light
-version:             0.2.6
+version:             0.2.7
 synopsis:            A lightweight plotting library, exporting to SVG
 description:         This library provides drawing and plotting datastructures and functions; it is aimed in particular at scientific visualization, but it also exposes its plotting primitives and a general purpose 2D geometry library.
 homepage:            https://github.com/ocramz/plot-light
@@ -47,6 +47,19 @@
                      -- , QuickCheck
                                           
 
+executable scatter
+  default-language:    Haskell2010
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  hs-source-dirs:      app/scatter
+  main-is:             Main.hs
+  build-depends:       base
+                     , plot-light
+                     , attoparsec
+                     , text
+                     , colour
+                     , blaze-svg
+                     , scientific
+                                          
 executable timeseries
   default-language:    Haskell2010
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
diff --git a/src/Graphics/Rendering/Plot/Light.hs b/src/Graphics/Rendering/Plot/Light.hs
--- a/src/Graphics/Rendering/Plot/Light.hs
+++ b/src/Graphics/Rendering/Plot/Light.hs
@@ -16,11 +16,12 @@
 --
 -- == Examples
 -- 
--- If you wish to try out the examples in this page, you will need to have these additional statements :
+-- If you wish to try out the examples in this page, you will need to have these import statements as well :
 --
--- @import Text.Blaze.Svg.Renderer.String (renderSvg)@
--- 
--- @import qualified Data.Colour.Names as C@
+-- > import Text.Blaze.Svg.Renderer.String (renderSvg) 
+-- > import qualified Data.Colour.Names as C
+-- > import qualified Data.Text.IO as T (readFile, writeFile)
+-- > import qualified Data.Text as T
 -- 
 -- === 1. Heatmap plot of a 2D function
 --
@@ -34,9 +35,7 @@
 -- where
 -- \( \rho^2 = x^2 + y^2 \) and \( \theta = \arctan(y/x) \).
 --
--- > import qualified Data.Text.IO as T (readFile, writeFile)
--- > import qualified Data.Text as T
--- >
+--
 -- > xPlot = 400
 -- > yPlot = 300
 -- >
@@ -80,11 +79,57 @@
 -- Next, we create the legend; in this case this is a `colourBar` element that requires the data bounds `vmin`, `vmax`.
 --
 -- As a last step, the SVG content is wrapped in the appropriate markdown by `svgHeader` and written to file.
+--
+--
+-- === 2. Scatter plot of 3D data
+--
+-- <<doc/fig/scatter.png>>
+--
+-- This example shows how to plot a collection of labelled points in the plane. Each sample row is represented by a `LabeledPoint`, in which the label is a scalar quantity.
+--
+-- The `scatterLP` function renders each data row as a glyph, by modifying a `ScatterPointData` record of default values via three functions that control the glyph size, contour line thickness and colour. This functionality can be exploited in creative ways to achieve effective infographics.
+--
+--
+-- > xPlot = 400
+-- > yPlot = 300
+-- > fnameOut = "data/scatter-1.svg"
+-- >
+-- > fdat = FigureData xPlot yPlot 0.1 0.8 0.1 0.9 10
+-- >
+-- > dats = zipWith LabeledPoint p_ l_ where
+-- >   l_ = [-5, -4 .. ]
+-- >   p_ = zipWith Point [4,7,12,23,90,34,24,5,6,12,3] [43,23,1,23,8,11,17,25,4,5]
+-- >
+-- > spdata = ScatterPointData Circle 3 3 C.red
+-- >
+-- >
+-- > main = do
+-- >  let
+-- >    frameTo = frameFromFigData fdat
+-- >    frameFrom = frameFromPoints $ _lp <$> dats
+-- >    vmin = minimum $ _lplabel <$> dats
+-- >    vmax = maximum $ _lplabel <$> dats     
+-- >    f l sz = 10/(1 + exp(-(0.3 * x)))
+-- >      where x = l + sz
+-- >    g _ w = w
+-- >    h l col = C.blend l' C.blue col
+-- >      where
+-- >        l' = (l - vmin)/(vmax - vmin)
+-- >    dats' = moveLabeledPointBwFrames frameFrom frameTo False True <$> dats
+-- >    svg_t = svgHeader xPlot yPlot $ do
+-- >      axes fdat frameFrom 2 C.black 10 10
+-- >      scatterLP f g h spdata dats'
+-- >      scatterLPBar fdat 50 vmin vmax 3 TopRight 100 f g h spdata
+-- >   T.writeFile fnameOut $ T.pack $ renderSvg svg_t
+--
+--
 
 module Graphics.Rendering.Plot.Light (
   -- * Plot types
   -- ** Heatmap
-  heatmap, heatmap', plotFun2, colourBar, 
+  heatmap, heatmap', plotFun2, colourBar,
+  -- ** Scatter
+  scatter, scatterLP, scatterLPBar, ScatterPointData(..), GlyphShape_(..),
   -- * Plot elements
   -- ** Geometrical primitives
   rect, rectCentered, squareCentered, circle, line, text, polyline, filledPolyline, pixel, pixel', 
diff --git a/src/Graphics/Rendering/Plot/Light/Internal.hs b/src/Graphics/Rendering/Plot/Light/Internal.hs
--- a/src/Graphics/Rendering/Plot/Light/Internal.hs
+++ b/src/Graphics/Rendering/Plot/Light/Internal.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE OverloadedStrings, DeriveFunctor #-}
-module Graphics.Rendering.Plot.Light.Internal (FigureData(..), Frame(..), mkFrame, mkFrameOrigin, frameToFrame, frameToFrameValue, frameFromPoints, frameFromFigData, xmin,xmax,ymin,ymax, width, height, figFWidth, figFHeight, Point(..), mkPoint, LabeledPoint(..), mkLabeledPoint, labelPoint, mapLabel, Axis(..), axes, meshGrid, subdivSegment, svgHeader, rect, rectCentered, squareCentered, circle, line, tick, ticks, axis, toPlot, text, pixel, pixel', pickColour, colourBar, plusGlyph, crossGlyph, polyline, filledPolyline, filledBand, candlestick, strokeLineJoin, LineStroke_(..), StrokeLineJoin_(..), TextAnchor_(..), LegendPosition_(..), V2(..), Mat2(..), DiagMat2(..), diagMat2, AdditiveGroup(..), VectorSpace(..), Hermitian(..), LinearMap(..), MultiplicativeSemigroup(..), MatrixGroup(..), Eps(..), norm2, normalize2, v2fromEndpoints, v2fromPoint, origin, (-.), pointRange, movePoint, moveLabeledPointV2, moveLabeledPointBwFrames, translateSvg, toSvgFrame, toSvgFrameLP, e1, e2, toFloat, wholeDecimal, blendTwo, palette) where
+module Graphics.Rendering.Plot.Light.Internal (FigureData(..), Frame(..), mkFrame, mkFrameOrigin, frameToFrame, frameToFrameValue, frameFromPoints, frameFromFigData, xmin,xmax,ymin,ymax, width, height, figFWidth, figFHeight, Point(..), mkPoint, LabeledPoint(..), mkLabeledPoint, labelPoint, mapLabel, Axis(..), axes, meshGrid, subdivSegment, svgHeader, rect, rectCentered, squareCentered, circle, line, tick, ticks, axis, toPlot, text, pixel, pixel', pickColour, colourBar, legendBar, plusGlyph, crossGlyph, polyline, filledPolyline, filledBand, candlestick, strokeLineJoin, LineStroke_(..), StrokeLineJoin_(..), TextAnchor_(..), LegendPosition_(..), V2(..), Mat2(..), DiagMat2(..), diagMat2, AdditiveGroup(..), VectorSpace(..), Hermitian(..), LinearMap(..), MultiplicativeSemigroup(..), MatrixGroup(..), Eps(..), norm2, normalize2, v2fromEndpoints, v2fromPoint, origin, (-.), pointRange, movePoint, moveLabeledPointV2, moveLabeledPointBwFrames, translateSvg, toSvgFrame, toSvgFrameLP, e1, e2, toFloat, wholeDecimal, blendTwo, palette) where
 
 import Data.Monoid ((<>))
 import qualified Data.Foldable as F (toList)
@@ -56,7 +56,6 @@
 
 
 
-
 -- | Create the SVG header
 svgHeader :: Real a =>
      a   -- ^ Image width (X axis)
@@ -247,14 +246,15 @@
             | otherwise = setPointX ox
 
 
--- -- | A pair of Cartesian axes
--- axes :: (Show a, RealFrac a) =>
---      FigureData a
---      -> a
---      -> C.Colour Double
---      -> Int
---      -> Int
---      -> Svg
+-- | A pair of Cartesian axes
+axes :: (Show a, RealFrac a) =>
+     FigureData a
+     -> Frame a
+     -> a
+     -> C.Colour Double
+     -> Int
+     -> Int
+     -> Svg
 axes fdat (Frame (Point xmi ymi) (Point xma yma)) sw col nx ny = do
   axis o X lenx sw col 0.01 Continuous fontsize (-45) TAEnd showlabf (V2 (-10) 0) plabx_
   axis o Y (- leny) sw col 0.01 Continuous fontsize 0 TAEnd showlabf (V2 (-10) 0) plaby_
@@ -267,7 +267,7 @@
     fontsize = figLabelFontSize fdat
     lenx = figFWidth fdat
     leny = figFHeight fdat
-    showlabf = T.pack . show . fromRational
+    showlabf x = T.pack $ show (fromRational x :: Fixed E2)
     
 
 
@@ -583,36 +583,58 @@
      -> LegendPosition_          -- ^ Legend position in the figure
      -> a                        -- ^ Colour bar length
      -> Svg
-colourBar fdat pal w vmin vmax n legpos legh = forM_ lps (colBarPx fdat pal w h vmin vmax) where
-  (legx, legy) = posCoeff legpos
-  legendX = fromRational $ figWidth fdat * legx 
-  legendY = fromRational $ figHeight fdat * legy
-  p1 = Point legendX (legendY + legh)
-  p2 = Point legendX legendY
-  lps = zipWith LabeledPoint (pointRange n p1 p2) v_
-  h = norm2 (p1 -. p2) / fromIntegral n
-  v_ = take (n+1) [vmin, vmin + dv ..]
-  dv = (vmax - vmin)/fromIntegral n
+colourBar fdat pal w vmin vmax n legpos legh =
+  legendBar (fromRational <$> fdat) w vmin vmax n legpos legh (colBarPx pal)
 
 
+legendBar
+  :: (Monad m, Enum t, Fractional t, Fractional a) =>
+     FigureData a
+     -> a
+     -> t
+     -> t
+     -> Int
+     -> LegendPosition_
+     -> a
+     -> (FigureData a -> a -> a -> t -> t -> LabeledPoint t a -> m b)
+     -> m ()
+legendBar fdat w vmin vmax n legpos legh fun = do
+  -- rect wrect hrect 1 (Just C.black) (Just C.white) prect
+  forM_ lps (fun fdat w h vmin vmax) where
+    wrect = 0.95 * (1 - figRightMFrac fdat) * figWidth fdat
+    hrect = 1.5 * legh
+    prect = movePoint (V2 (-0.5 * w) (-0.5 * w)) p2
+    (legx, legy) = posCoeff legpos
+    legendX = figWidth fdat * legx 
+    legendY = figHeight fdat * legy
+    p1 = Point legendX (legendY + legh)
+    p2 = Point legendX legendY
+    lps = zipWith LabeledPoint (pointRange n p1 p2) v_
+    h = legh / fromIntegral n
+    v_ = take (n+1) [vmin, vmin + dv ..]
+    dv = (vmax - vmin)/fromIntegral n
 
--- colBarPx
---   :: (Show a, RealFrac a, RealFrac t) =>
---      FigureData a1
---      -> [C.Colour Double]
---      -> a
---      -> a
---      -> t
---      -> t
---      -> LabeledPoint t a
---      -> Svg
-colBarPx fdat pal w h vmin vmax (LabeledPoint p val) = do
-  text 0 (figLabelFontSize fdat) C.black TAStart (T.pack $ show (rr val :: Fixed E6)) (V2 (1.1*w) (0.5*h)) p
+
+colBarPx
+  :: (Show a, RealFrac a, RealFrac t) =>
+     [C.Colour Double]       
+     -> FigureData a1
+     -> a
+     -> a
+     -> t
+     -> t
+     -> LabeledPoint t a
+     -> Svg
+colBarPx pal fdat w h vmin vmax (LabeledPoint p val) = do
+  text 0 (figLabelFontSize fdat) C.black TAStart (T.pack $ show (rr val :: Fixed E3)) (V2 (1.1*w) (0.5*h)) p
   rectCentered w h 0 Nothing (Just $ pickColour pal vmin vmax val) p
   
 
 
 
+
+    
+
   
 -- * Helpers
 
@@ -623,8 +645,7 @@
 
 -- **
 
-rr :: (Real a, Fractional c) => a -> c
-rr = fromRational . toRational
+
 
 
 
diff --git a/src/Graphics/Rendering/Plot/Light/Internal/Geometry.hs b/src/Graphics/Rendering/Plot/Light/Internal/Geometry.hs
--- a/src/Graphics/Rendering/Plot/Light/Internal/Geometry.hs
+++ b/src/Graphics/Rendering/Plot/Light/Internal/Geometry.hs
@@ -274,7 +274,7 @@
 moveLabeledPointV2 = moveLabeledPoint . movePoint
 
 
--- | `pointRange n p q` returns a list of `n+1` equi-spaced `Point`s between `p` and `q` (i.e. the input points are included as the first and last points in the list)
+-- | `pointRange n p q` returns a list of equi-spaced `Point`s between `p` and `q`.
 pointRange :: (Fractional a, Integral n) =>
      n -> Point a -> Point a -> [Point a]
 pointRange n p q = [ movePoint (fromIntegral x .* vnth) p | x <- [0 .. n]]
@@ -298,14 +298,20 @@
       x <- take nx $ subdivSegment xmi xma nx,
       y <- take ny $ subdivSegment ymi yma ny]
 
-subdivSegment
-  :: (Enum a, RealFrac a) => a -> a -> Int -> [a]
-subdivSegment x1 x2 n = [xmin, xmin + dx ..] where
-  dx = fromRational . toRational $ l / fromIntegral n
+-- subdivSegment
+--   :: (Enum a, RealFrac a) => a -> a -> Int -> [a]
+-- subdivSegment x1 x2 n = [xmin, xmin + dx ..] where
+--   dx = fromRational . toRational $ l / fromIntegral n
+--   xmin = min x1 x2
+--   xmax = max x1 x2
+--   l = xmax - xmin
+
+subdivSegment :: (Real a, Enum b, RealFrac b) => a -> a -> Int -> [b]
+subdivSegment x1 x2 n = f <$> [0, 1 ..] where
   xmin = min x1 x2
   xmax = max x1 x2
-  l = xmax - xmin
-
+  l = fromRational $ toRational (xmax - xmin)
+  f x  = x * l/fromIntegral n + fromRational (toRational xmin)
 
 
 fromFrame :: Fractional a => Frame a -> V2 a -> V2 a
diff --git a/src/Graphics/Rendering/Plot/Light/Internal/Utils.hs b/src/Graphics/Rendering/Plot/Light/Internal/Utils.hs
--- a/src/Graphics/Rendering/Plot/Light/Internal/Utils.hs
+++ b/src/Graphics/Rendering/Plot/Light/Internal/Utils.hs
@@ -22,6 +22,9 @@
 
 -- ** Numeric formats
 
+rr :: (Real a, Fractional c) => a -> c
+rr = fromRational . toRational
+
 toFloat :: Scientific -> Float
 toFloat x = toRealFloat x :: Float
 
diff --git a/src/Graphics/Rendering/Plot/Light/PlotTypes/Heatmap.hs b/src/Graphics/Rendering/Plot/Light/PlotTypes/Heatmap.hs
--- a/src/Graphics/Rendering/Plot/Light/PlotTypes/Heatmap.hs
+++ b/src/Graphics/Rendering/Plot/Light/PlotTypes/Heatmap.hs
@@ -1,5 +1,7 @@
+{-# language RecordWildCards #-}
 module Graphics.Rendering.Plot.Light.PlotTypes.Heatmap (heatmap, heatmap', plotFun2) where
 
+import Control.Monad.State
 import Data.Scientific (Scientific, toRealFloat)
 import Graphics.Rendering.Plot.Light.Internal
 
@@ -8,10 +10,37 @@
 import Control.Arrow ((***), (&&&))
 import Control.Monad (forM_)
 
--- import qualified Data.Colour.Names as C
+
 import qualified Data.Colour as C
+import qualified Data.Colour.Names as C
 import Data.Colour.Palette.BrewerSet
 -- import Text.Blaze.Svg
+
+
+
+data MeshGrid2d a = MeshGrid2d {
+    mgFrame :: Frame a
+  , mgNx :: Int
+  , mgNy :: Int
+                           } deriving (Eq, Show)
+
+data Heatmap a = Heatmap {
+    hmMesh :: MeshGrid2d a
+  , hmPalette :: [C.Colour Double]
+  , hmValMin :: a
+  , hmValMax :: a
+                         } deriving (Eq, Show)
+
+heatmapDefaults :: Num a => Heatmap a
+heatmapDefaults = Heatmap mesh pal 0 1
+  where
+    pal = palette [C.red, C.white, C.blue] 20
+    pmin = Point 0 0
+    pmax = Point 1 1
+    mesh = MeshGrid2d (Frame pmin pmax) 20 20
+
+  
+
 
 
 
diff --git a/src/Graphics/Rendering/Plot/Light/PlotTypes/Scatter.hs b/src/Graphics/Rendering/Plot/Light/PlotTypes/Scatter.hs
--- a/src/Graphics/Rendering/Plot/Light/PlotTypes/Scatter.hs
+++ b/src/Graphics/Rendering/Plot/Light/PlotTypes/Scatter.hs
@@ -1,24 +1,118 @@
 module Graphics.Rendering.Plot.Light.PlotTypes.Scatter where
 
 import Graphics.Rendering.Plot.Light.Internal
+import Graphics.Rendering.Plot.Light.Internal.Utils
 
+import Data.Fixed
 import Data.Maybe (fromMaybe)
 import Control.Monad (forM_)
 import Text.Blaze.Svg
 import qualified Data.Colour as C
 import qualified Data.Colour.Palette.BrewerSet as CP
 import qualified Data.Colour.Names as C
+import qualified Data.Text as T
 
 
+-- | Scatter plot
+--
+-- Every point in the plot has the same parameters, as declared in the `ScatterPointData` record
+scatter
+  :: (Foldable t, Show a, RealFrac a) =>
+     ScatterPointData a
+     -> t (Point a)
+     -> Svg
+scatter (ScatterPointData glshape w sw fcol) ps = 
+  forM_ ps $ glyph w sw glshape Nothing (Just fcol)
 
-data GlyphShape = Square | Circle | Cross | Plus deriving (Eq, Show, Enum)
 
+
+
+
+-- | Parametric scatter plot
+--
+-- The parameters of every point in the scatter plot are modulated according to the label, using the three functions.
+--
+-- This can be used to produce rich infographics, in which e.g. the colour and size of the glyphs carry additional information.
+scatterLP
+  :: (Foldable t, RealFrac a, Show a) =>
+     (l -> b -> a)
+     -> (l -> b -> a)
+     -> (l -> C.Colour Double -> C.Colour Double)
+     -> ScatterPointData b
+     -> t (LabeledPoint l a)
+     -> Svg
+scatterLP f g h spdat lps = forM_ lps (scatterLP1 f g h spdat)
+
+
+scatterLP1
+  :: (Show a, RealFrac a) =>
+     (l -> b -> a)
+     -> (l -> b -> a)
+     -> (l -> C.Colour Double -> C.Colour Double)
+     -> ScatterPointData b
+     -> LabeledPoint l a
+     -> Svg
+scatterLP1 f g h spdat lp = glyph w' sw' sh Nothing (Just col') (_lp lp)
+ where
+    ScatterPointData sh w' sw' col' = modifyScatterPoint f g h spdat lp
+
+
+
+scatterLPBar
+  :: (RealFrac t, Enum t, RealFrac b, Show b) =>
+     FigureData b
+     -> b
+     -> t
+     -> t
+     -> Int
+     -> LegendPosition_
+     -> b
+     -> (t -> b -> b)
+     -> (t -> b -> b)
+     -> (t -> C.Colour Double -> C.Colour Double)
+     -> ScatterPointData b
+     -> Svg
+scatterLPBar fdat w vmin vmax n legpos legh f g h spdat = legendBar fdat w vmin vmax n legpos legh fun where
+  wglyph = spSize spdat
+  fun _ _ _ _ _ lp@(LabeledPoint p val) = do
+    scatterLP1 f g h spdat lp
+    text 0 (figLabelFontSize fdat) C.black TAStart (T.pack $ show (rr val :: Fixed E3))   (V2 (2*wglyph) (0.5*wglyph)) p
+
+
+  
+      
+-- | Parameters for a scatterplot glyph
+data ScatterPointData a = ScatterPointData
+  {
+    spGlyphShape :: GlyphShape_
+  , spSize :: a
+  , spStrokeWidth :: a
+  , spColour :: C.Colour Double
+  } deriving (Eq, Show)
+
+
+modifyScatterPoint
+  :: (a -> b -> c)
+     -> (a -> b -> c)
+     -> (a -> C.Colour Double -> C.Colour Double)
+     -> ScatterPointData b
+     -> LabeledPoint a d
+     -> ScatterPointData c
+modifyScatterPoint f g h (ScatterPointData glsh sz w col) lp =
+  ScatterPointData glsh (f lab sz) (g lab w) (h lab col)
+  where
+    lab = _lplabel lp
+
+
+-- | Glyph shape
+data GlyphShape_ = Square | Circle | Cross | Plus deriving (Eq, Show, Enum)
+
 -- | Scatterplot glyph shapes
 glyph
   :: (Show a, RealFrac a) =>
      a
      -> a
-     -> GlyphShape
+     -> GlyphShape_
      -> Maybe (C.Colour Double)
      -> Maybe (C.Colour Double)
      -> Point a
@@ -30,11 +124,10 @@
 
 
 -- | Utility function for cycling glyph colours and shapes (i.e. unique combinations of these make it easy to tell different datasets apart)
-cycleGlyphCols :: (CP.ColorCat, Int) -> Int -> [(CP.Kolor, GlyphShape)]
+cycleGlyphCols :: (CP.ColorCat, Int) -> Int -> [(CP.Kolor, GlyphShape_)]
 cycleGlyphCols (pal, n) nsets = take nsets $ zip (cycle $ CP.brewerSet pal n ) (cycle [Square, Circle ..])
 
 
-scatter figdata = forM_
 
 
 
