diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,2 +1,11 @@
+	0.3
+
+	Stackage LTS bump to 11.0 (GHC 8.4.1)
+	Removed dependencies: palette, attoparsec
+	Moved data and examples to plot-light-examples
+	Add bilinear interpolation
+	
+	
 	0.2.9
+	
 	Bumped attoparsec-time to >= 1 to reflect module structure change
diff --git a/app/heatmap/Main.hs b/app/heatmap/Main.hs
deleted file mode 100644
--- a/app/heatmap/Main.hs
+++ /dev/null
@@ -1,96 +0,0 @@
-module Main where
-
--- import Control.Monad (forM_)
--- import Data.Ratio
-
-import Graphics.Rendering.Plot.Light
-import Graphics.Rendering.Plot.Light.PlotTypes
-
-import qualified Data.Attoparsec.Text as A
-import qualified Data.Text as T 
-import qualified Data.Text.IO as T (readFile, writeFile)
-import Data.Scientific (Scientific, toRealFloat)
-import Text.Blaze.Svg.Renderer.String (renderSvg)
-import Text.Blaze.Svg
-
-import qualified Data.Colour.Names as C
-import qualified Data.Colour as C
-import qualified Data.Colour.Palette.BrewerSet as CP
-import qualified Data.Colour.Palette.Harmony as CH
-
-
-fname = "data/heatmap-bw"
-
-xPlot = 400
-yPlot = 300
-fnameOut = "data/heatmap-1.svg"
-
--- fdat :: FigureData Double
-fdat = FigureData xPlot yPlot 0.1 0.8 0.1 0.9 10
-
-palette0 = palette [C.blue, C.white, C.red] 15
-
-
--- main :: IO ()
--- main = do
---   dat <- T.readFile fname
---   let pd = A.parseOnly (gridNum space) dat
---   case pd of Left e -> error e
---              Right d -> do
---                   let pixels = heatmap fdat palette0 d
---                       svg_t = svgHeader xPlot yPlot pixels
---                   -- putStrLn $ renderSvg svg_t
---                   T.writeFile fnameOut $ T.pack $ renderSvg svg_t 
-    
-  
-
-
-main = do
-  let 
-    p1 = Point (-2) (-2)
-    p2 = Point 2 2
-    frame = mkFrame p1 p2
-    nx = 50
-    ny = 50
-    f x y = cos ( pi * theta ) * sin r 
-      where
-      r = x'**2 + y'**2
-      theta = atan2 y' x'
-      (x', y') = (fromRational x, fromRational y)
-    lps = plotFun2 f $ meshGrid frame nx ny
-    vmin = minimum $ _lplabel <$> lps
-    vmax = maximum $ _lplabel <$> lps       
-    pixels = heatmap' fdat palette0 frame (fromIntegral nx) (fromIntegral ny) lps
-    cbar = colourBar fdat palette0 10 vmin vmax 10 TopRight 100
-    svg_t = svgHeader xPlot yPlot $ do
-      axes fdat frame 2 C.black 10 10
-      pixels
-      cbar
-  T.writeFile "data/heatmap-3.svg" $ T.pack $ renderSvg svg_t
-  
-        
-
--- withMeshGrid :: (RealFrac a, Enum a) =>
---     Point a -> Point a -> a -> a -> (Frame a -> [Point a] -> t) -> t
--- withMeshGrid p1 p2 nx ny f =
---   withFrame p1 p2 $ \fr -> let
---   grid = meshGrid fr nx ny in f fr grid 
-
--- withFrame p1 p2 f = f frame where
---   frame = mkFrame p1 p2
-
-
-
-
--- parsers
-
--- | Parse a row of numbers, separated by `sep`
-rowNums :: A.Parser s -> A.Parser [Scientific]
-rowNums = A.sepBy A.scientific
-
-rowNumSpace :: A.Parser [Scientific]
-rowNumSpace = rowNums space
-
--- | parse a grid of numbers, separated by `sep`
-gridNum :: A.Parser s -> A.Parser [[Scientific]]
-gridNum sep = A.sepBy (rowNums sep) A.endOfLine
diff --git a/app/scatter/Main.hs b/app/scatter/Main.hs
deleted file mode 100644
--- a/app/scatter/Main.hs
+++ /dev/null
@@ -1,47 +0,0 @@
-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/app/timeseries/Main.hs b/app/timeseries/Main.hs
deleted file mode 100644
--- a/app/timeseries/Main.hs
+++ /dev/null
@@ -1,93 +0,0 @@
-{-# language OverloadedStrings #-}
-module Main where
-
--- import Control.Arrow ((***), (&&&))
-
-import Graphics.Rendering.Plot.Light
-import Graphics.Rendering.Plot.Light.PlotTypes
-  
-import qualified Data.Attoparsec.Text as A
-import qualified Attoparsec.Time.Text as AT
-import qualified Data.Text as T 
-import qualified Data.Text.IO as T (readFile, writeFile)
-import Data.Scientific (Scientific, toRealFloat)
-import Text.Blaze.Svg.Renderer.String (renderSvg)
-import qualified Data.Colour.Names as C
-
-import Control.Applicative ((<|>))
-import Data.Time (Day, TimeOfDay)
-
-fname = "data/forex"
-
-xPlot = 400
-yPlot = 300
-fnameOut = "data/forex_plot_5.svg"
-
-fdat = FigureData xPlot yPlot 0.1 0.9 0.1 0.85 10
-
-
-main = do
-  dat <- T.readFile fname
-  let pd = A.parseOnly parseFxDataset dat
-  case pd of Left e -> error e
-             Right d -> 
-               do
-               let
-                 lps =  tspToLP fhi (\_ x -> x) <$> d
-                 -- figure = tsAxis fdat fop fcl fhi flo 1 C.black (-45) Nothing Nothing lps       
-                 figure = tsAxis' fdat flo fhi C.magenta lps
-                 svg_t = svgHeader xPlot yPlot figure
-               -- putStrLn $ renderSvg svg_t
-               T.writeFile fnameOut $ T.pack $ renderSvg svg_t
-                 where
-                   fhi = toFloat . rateHigh
-                   flo = toFloat . rateLow
-                   fop = toFloat . rateOpen
-                   fcl = toFloat . rateClose
-
-
-
-
-avgTs :: FxRow Scientific -> Float
-avgTs x = 0.5 * (h + l) where
-  h = toFloat (rateHigh x)
-  l = toFloat (rateLow x)
-
-
-
-
-
--- Forex time series parsers - related
-
-
-
-
-
-
-
-
-
--- * Forex dataset
-
-parseFxDataset :: A.Parser [TsPoint (FxRow Scientific)]
-parseFxDataset = A.sepBy parseFxRow A.endOfLine
-
-parseFxRow :: A.Parser (TsPoint (FxRow Scientific))
-parseFxRow = do
-  (d, t) <- parseDateTime
-  _ <- comma
-  open <- A.scientific
-  _ <- comma
-  hi <- A.scientific
-  _ <- comma
-  lo <- A.scientific
-  _ <- comma
-  close <- A.scientific
-  pure $ Tsp (Tick d t) (FxRow open hi lo close)
-
-parseDateTime :: A.Parser (Day, TimeOfDay)
-parseDateTime = do
-  d <- AT.dayInISO8601
-  _ <- space
-  t <- AT.timeOfDayInISO8601
-  return (d, t)
diff --git a/data/forex b/data/forex
deleted file mode 100644
--- a/data/forex
+++ /dev/null
@@ -1,174 +0,0 @@
-2017-06-26 21:00:00,1.0876,1.0880,1.0872,1.0874
-2017-06-26 20:00:00,1.0873,1.0875,1.0872,1.0875
-2017-06-26 19:00:00,1.0874,1.0875,1.0873,1.0874
-2017-06-26 18:00:00,1.0870,1.0875,1.0870,1.0875
-2017-06-26 17:00:00,1.0873,1.0873,1.0870,1.0870
-2017-06-26 16:00:00,1.0869,1.0873,1.0867,1.0873
-2017-06-26 15:00:00,1.0873,1.0876,1.0869,1.0870
-2017-06-26 14:00:00,1.0875,1.0877,1.0871,1.0873
-2017-06-26 13:00:00,1.0882,1.0883,1.0875,1.0875
-2017-06-26 12:00:00,1.0882,1.0888,1.0880,1.0885
-2017-06-26 11:00:00,1.0881,1.0882,1.0879,1.0881
-2017-06-26 10:00:00,1.0881,1.0883,1.0879,1.0881
-2017-06-26 09:00:00,1.0864,1.0879,1.0862,1.0879
-2017-06-26 08:00:00,1.0858,1.0866,1.0858,1.0862
-2017-06-26 07:00:00,1.0860,1.0862,1.0857,1.0860
-2017-06-26 06:00:00,1.0855,1.0859,1.0854,1.0859
-2017-06-26 05:00:00,1.0857,1.0859,1.0856,1.0856
-2017-06-26 04:00:00,1.0858,1.0859,1.0857,1.0857
-2017-06-26 03:00:00,1.0855,1.0859,1.0855,1.0858
-2017-06-26 02:00:00,1.0856,1.0857,1.0855,1.0855
-2017-06-26 01:00:00,1.0855,1.0858,1.0855,1.0856
-2017-06-26 00:00:00,1.0856,1.0856,1.0855,1.0856
-2017-06-25 23:00:00,1.0855,1.0856,1.0854,1.0855
-2017-06-25 22:00:00,1.0855,1.0857,1.0851,1.0855
-2017-06-25 21:00:00,1.0859,1.0863,1.0851,1.0855
-2017-06-23 20:00:00,1.0855,1.0858,1.0852,1.0852
-2017-06-23 19:00:00,1.0852,1.0855,1.0851,1.0855
-2017-06-23 18:00:00,1.0854,1.0856,1.0852,1.0852
-2017-06-23 17:00:00,1.0856,1.0856,1.0852,1.0854
-2017-06-23 16:00:00,1.0853,1.0854,1.0851,1.0854
-2017-06-23 15:00:00,1.0850,1.0853,1.0849,1.0853
-2017-06-23 14:00:00,1.0852,1.0853,1.0847,1.0848
-2017-06-23 13:00:00,1.0856,1.0859,1.0849,1.0849
-2017-06-23 12:00:00,1.0856,1.0856,1.0851,1.0854
-2017-06-23 11:00:00,1.0848,1.0856,1.0848,1.0856
-2017-06-23 10:00:00,1.0854,1.0855,1.0845,1.0848
-2017-06-23 09:00:00,1.0842,1.0852,1.0841,1.0852
-2017-06-23 08:00:00,1.0844,1.0844,1.0837,1.0843
-2017-06-23 07:00:00,1.0842,1.0848,1.0840,1.0845
-2017-06-23 06:00:00,1.0838,1.0845,1.0838,1.0842
-2017-06-23 05:00:00,1.0837,1.0839,1.0837,1.0838
-2017-06-23 04:00:00,1.0837,1.0838,1.0836,1.0837
-2017-06-23 03:00:00,1.0837,1.0837,1.0836,1.0836
-2017-06-23 02:00:00,1.0838,1.0838,1.0835,1.0836
-2017-06-23 01:00:00,1.0837,1.0839,1.0836,1.0837
-2017-06-23 00:00:00,1.0837,1.0838,1.0835,1.0837
-2017-06-22 23:00:00,1.0838,1.0838,1.0836,1.0837
-2017-06-22 22:00:00,1.0839,1.0843,1.0837,1.0838
-2017-06-22 21:00:00,1.0838,1.0856,1.0837,1.0838
-2017-06-22 20:00:00,1.0838,1.0839,1.0837,1.0838
-2017-06-22 19:00:00,1.0842,1.0842,1.0836,1.0837
-2017-06-22 18:00:00,1.0841,1.0843,1.0840,1.0841
-2017-06-22 17:00:00,1.0845,1.0847,1.0840,1.0841
-2017-06-22 16:00:00,1.0847,1.0848,1.0843,1.0845
-2017-06-22 15:00:00,1.0848,1.0851,1.0843,1.0845
-2017-06-22 14:00:00,1.0852,1.0858,1.0844,1.0850
-2017-06-22 13:00:00,1.0860,1.0864,1.0851,1.0851
-2017-06-22 12:00:00,1.0873,1.0873,1.0862,1.0862
-2017-06-22 11:00:00,1.0869,1.0873,1.0868,1.0871
-2017-06-22 10:00:00,1.0871,1.0874,1.0869,1.0870
-2017-06-22 09:00:00,1.0870,1.0871,1.0866,1.0870
-2017-06-22 08:00:00,1.0861,1.0870,1.0860,1.0869
-2017-06-22 07:00:00,1.0857,1.0862,1.0855,1.0861
-2017-06-22 06:00:00,1.0863,1.0864,1.0857,1.0857
-2017-06-22 05:00:00,1.0863,1.0864,1.0862,1.0863
-2017-06-22 04:00:00,1.0863,1.0864,1.0861,1.0863
-2017-06-22 03:00:00,1.0860,1.0863,1.0860,1.0863
-2017-06-22 02:00:00,1.0862,1.0862,1.0859,1.0860
-2017-06-22 01:00:00,1.0859,1.0863,1.0859,1.0863
-2017-06-22 00:00:00,1.0861,1.0863,1.0860,1.0860
-2017-06-21 23:00:00,1.0861,1.0862,1.0860,1.0861
-2017-06-21 22:00:00,1.0861,1.0862,1.0860,1.0861
-2017-06-21 21:00:00,1.0862,1.0866,1.0860,1.0861
-2017-06-21 20:00:00,1.0861,1.0862,1.0859,1.0861
-2017-06-21 19:00:00,1.0862,1.0862,1.0860,1.0860
-2017-06-21 18:00:00,1.0860,1.0862,1.0860,1.0861
-2017-06-21 17:00:00,1.0858,1.0861,1.0855,1.0859
-2017-06-21 16:00:00,1.0860,1.0862,1.0858,1.0858
-2017-06-21 15:00:00,1.0864,1.0864,1.0858,1.0858
-2017-06-21 14:00:00,1.0859,1.0866,1.0858,1.0865
-2017-06-21 13:00:00,1.0859,1.0861,1.0854,1.0856
-2017-06-21 12:00:00,1.0860,1.0862,1.0858,1.0860
-2017-06-21 11:00:00,1.0864,1.0865,1.0856,1.0860
-2017-06-21 10:00:00,1.0855,1.0863,1.0855,1.0863
-2017-06-21 09:00:00,1.0855,1.0858,1.0854,1.0854
-2017-06-21 08:00:00,1.0848,1.0854,1.0846,1.0854
-2017-06-21 07:00:00,1.0852,1.0853,1.0848,1.0850
-2017-06-21 06:00:00,1.0852,1.0853,1.0849,1.0851
-2017-06-21 05:00:00,1.0851,1.0852,1.0851,1.0851
-2017-06-21 04:00:00,1.0851,1.0852,1.0850,1.0851
-2017-06-21 03:00:00,1.0851,1.0853,1.0851,1.0852
-2017-06-21 02:00:00,1.0855,1.0855,1.0849,1.0851
-2017-06-21 01:00:00,1.0854,1.0855,1.0853,1.0855
-2017-06-21 00:00:00,1.0856,1.0856,1.0850,1.0852
-2017-06-20 23:00:00,1.0856,1.0857,1.0855,1.0856
-2017-06-20 22:00:00,1.0866,1.0871,1.0856,1.0856
-2017-06-20 21:00:00,1.0858,1.0870,1.0856,1.0861
-2017-06-20 20:00:00,1.0855,1.0858,1.0855,1.0858
-2017-06-20 19:00:00,1.0855,1.0857,1.0854,1.0855
-2017-06-20 18:00:00,1.0857,1.0858,1.0855,1.0855
-2017-06-20 17:00:00,1.0857,1.0859,1.0856,1.0858
-2017-06-20 16:00:00,1.0858,1.0861,1.0857,1.0858
-2017-06-20 15:00:00,1.0860,1.0862,1.0858,1.0860
-2017-06-20 14:00:00,1.0859,1.0861,1.0857,1.0859
-2017-06-20 13:00:00,1.0864,1.0865,1.0858,1.0859
-2017-06-20 12:00:00,1.0854,1.0867,1.0854,1.0865
-2017-06-20 11:00:00,1.0864,1.0864,1.0854,1.0855
-2017-06-20 10:00:00,1.0861,1.0865,1.0860,1.0865
-2017-06-20 09:00:00,1.0871,1.0875,1.0857,1.0864
-2017-06-20 08:00:00,1.0874,1.0877,1.0868,1.0870
-2017-06-20 07:00:00,1.0879,1.0880,1.0864,1.0872
-2017-06-20 06:00:00,1.0878,1.0881,1.0877,1.0880
-2017-06-20 05:00:00,1.0881,1.0882,1.0877,1.0877
-2017-06-20 04:00:00,1.0879,1.0882,1.0878,1.0880
-2017-06-20 03:00:00,1.0880,1.0881,1.0879,1.0879
-2017-06-20 02:00:00,1.0880,1.0881,1.0878,1.0880
-2017-06-20 01:00:00,1.0879,1.0880,1.0878,1.0880
-2017-06-20 00:00:00,1.0880,1.0881,1.0878,1.0878
-2017-06-19 23:00:00,1.0880,1.0880,1.0877,1.0880
-2017-06-19 22:00:00,1.0882,1.0883,1.0879,1.0879
-2017-06-19 21:00:00,1.0878,1.0890,1.0875,1.0882
-2017-06-19 20:00:00,1.0878,1.0879,1.0877,1.0878
-2017-06-19 19:00:00,1.0879,1.0879,1.0877,1.0879
-2017-06-19 18:00:00,1.0879,1.0879,1.0876,1.0877
-2017-06-19 17:00:00,1.0875,1.0879,1.0875,1.0878
-2017-06-19 16:00:00,1.0877,1.0879,1.0875,1.0876
-2017-06-19 15:00:00,1.0877,1.0879,1.0873,1.0877
-2017-06-19 14:00:00,1.0883,1.0883,1.0877,1.0881
-2017-06-19 13:00:00,1.0877,1.0885,1.0875,1.0885
-2017-06-19 12:00:00,1.0869,1.0882,1.0868,1.0882
-2017-06-19 11:00:00,1.0879,1.0880,1.0869,1.0870
-2017-06-19 10:00:00,1.0876,1.0880,1.0873,1.0878
-2017-06-19 09:00:00,1.0880,1.0881,1.0875,1.0876
-2017-06-19 08:00:00,1.0883,1.0885,1.0877,1.0881
-2017-06-19 07:00:00,1.0903,1.0903,1.0889,1.0890
-2017-06-19 06:00:00,1.0905,1.0910,1.0904,1.0905
-2017-06-19 05:00:00,1.0905,1.0905,1.0903,1.0904
-2017-06-19 04:00:00,1.0902,1.0906,1.0902,1.0905
-2017-06-19 03:00:00,1.0903,1.0903,1.0901,1.0902
-2017-06-19 02:00:00,1.0904,1.0905,1.0902,1.0903
-2017-06-19 01:00:00,1.0903,1.0905,1.0903,1.0904
-2017-06-19 00:00:00,1.0906,1.0906,1.0902,1.0902
-2017-06-18 23:00:00,1.0905,1.0905,1.0902,1.0905
-2017-06-18 22:00:00,1.0903,1.0905,1.0901,1.0905
-2017-06-18 21:00:00,1.0911,1.0911,1.0902,1.0907
-2017-06-16 20:00:00,1.0900,1.0907,1.0898,1.0906
-2017-06-16 19:00:00,1.0901,1.0902,1.0898,1.0900
-2017-06-16 18:00:00,1.0904,1.0904,1.0900,1.0902
-2017-06-16 17:00:00,1.0901,1.0902,1.0899,1.0901
-2017-06-16 16:00:00,1.0902,1.0902,1.0898,1.0901
-2017-06-16 15:00:00,1.0898,1.0902,1.0893,1.0901
-2017-06-16 14:00:00,1.0890,1.0898,1.0886,1.0898
-2017-06-16 13:00:00,1.0886,1.0888,1.0883,1.0884
-2017-06-16 12:00:00,1.0885,1.0891,1.0884,1.0886
-2017-06-16 11:00:00,1.0889,1.0890,1.0885,1.0885
-2017-06-16 10:00:00,1.0881,1.0893,1.0881,1.0890
-2017-06-16 09:00:00,1.0882,1.0883,1.0877,1.0882
-2017-06-16 08:00:00,1.0876,1.0882,1.0876,1.0882
-2017-06-16 07:00:00,1.0871,1.0876,1.0869,1.0875
-2017-06-16 06:00:00,1.0870,1.0874,1.0867,1.0874
-2017-06-16 05:00:00,1.0871,1.0872,1.0869,1.0870
-2017-06-16 04:00:00,1.0871,1.0872,1.0870,1.0870
-2017-06-16 03:00:00,1.0871,1.0872,1.0870,1.0871
-2017-06-16 02:00:00,1.0872,1.0872,1.0869,1.0871
-2017-06-16 01:00:00,1.0872,1.0873,1.0870,1.0872
-2017-06-16 00:00:00,1.0874,1.0874,1.0871,1.0872
-2017-06-15 23:00:00,1.0872,1.0873,1.0871,1.0872
-2017-06-15 22:00:00,1.0875,1.0875,1.0871,1.0872
-2017-06-15 21:00:00,1.0873,1.0876,1.0871,1.0875
-2017-06-15 20:00:00,1.0874,1.0875,1.0871,1.0873
-2017-06-15 19:00:00,1.0875,1.0875,1.0873,1.0873
-2017-06-15 18:00:00,1.0874,1.0875,1.0873,1.0874
-2017-06-15 17:00:00,1.0872,1.0874,1.0871,1.0872
-2017-06-15 16:00:00,1.0873,1.0874,1.0871,1.0871
diff --git a/data/heatmap-bw b/data/heatmap-bw
deleted file mode 100644
--- a/data/heatmap-bw
+++ /dev/null
@@ -1,6 +0,0 @@
-6 5 4 3 1 0
-3 2 2 0 0 1
-0 0 0 0 1 0
-0 0 0 0 2 3
-0 0 1 2 4 3
-0 1 2 3 4 5
diff --git a/plot-light.cabal b/plot-light.cabal
--- a/plot-light.cabal
+++ b/plot-light.cabal
@@ -1,24 +1,23 @@
 name:                plot-light
-version:             0.2.9
+version:             0.3
 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.
+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 small but general purpose 2D geometry library.
+                     
 homepage:            https://github.com/ocramz/plot-light
 license:             BSD3
 license-file:        LICENSE
 author:              Marco Zocca
 maintainer:          zocca marco gmail
-copyright:           2017 Marco Zocca
+copyright:           2017-2018 Marco Zocca
 category:            Graphics
 build-type:          Simple
 extra-source-files:  README.md
                      CHANGELOG.md
 extra-doc-files:     doc/fig/*.png
 cabal-version:       >=1.18
-tested-with:         GHC == 8.0.2
-data-dir:            data
-data-files:          forex
-                     heatmap-bw
+tested-with:         GHC == 8.0.2, GHC == 8.4.1
 
+
 library
   default-language:    Haskell2010
   ghc-options:         -Wall -Wno-missing-signatures -Wno-type-defaults -Wno-name-shadowing
@@ -36,65 +35,21 @@
                        Graphics.Rendering.Plot.Light.Internal.Geometry
                        Graphics.Rendering.Plot.Light.Internal.Utils
                        Data.Parsers
-  build-depends:       attoparsec
-                     , base >= 4.7 && < 5
+  build-depends:       base >= 4.7 && < 5
                      , blaze-svg
                      , colour
                      , containers >= 0.5.7.1
                      , mtl
-                     , palette
                      , scientific
                      , text
                      , time
                      , data-default
-                     -- * DEBUG
-                     , hspec    
-                     , QuickCheck
+                     -- -- * DEBUG
+                     -- , hspec    
+                     -- , 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
-  hs-source-dirs:      app/timeseries
-  main-is:             Main.hs
-  build-depends:       base
-                     , plot-light
-                     , attoparsec
-                     , attoparsec-time >= 1
-                     , time
-                     , text
-                     , colour
-                     , blaze-svg
-                     , scientific
-
-executable heatmap
-  default-language:    Haskell2010
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
-  hs-source-dirs:      app/heatmap
-  main-is:             Main.hs
-  build-depends:       base
-                     , plot-light
-                     , attoparsec
-                     , time
-                     , text
-                     , colour
-                     , palette
-                     , blaze-svg
-                     , scientific                     
-
+          
 test-suite spec
   default-language:    Haskell2010
   ghc-options:         -Wall
diff --git a/src/Data/Parsers.hs b/src/Data/Parsers.hs
--- a/src/Data/Parsers.hs
+++ b/src/Data/Parsers.hs
@@ -1,6 +1,6 @@
 module Data.Parsers where
-import qualified Data.Attoparsec.Text as A
+-- import qualified Data.Attoparsec.Text as A
 
-space, comma :: A.Parser Char
-space = A.char ' '
-comma = A.char ','
+-- space, comma :: A.Parser Char
+-- space = A.char ' '
+-- comma = A.char ','
diff --git a/src/Data/TimeSeries.hs b/src/Data/TimeSeries.hs
--- a/src/Data/TimeSeries.hs
+++ b/src/Data/TimeSeries.hs
@@ -32,16 +32,24 @@
     
 -- | Map a rational onto a Tick
 toTick :: Rational -> Tick
-toTick n = Tick d t where
-  t = dayFractionToTimeOfDay dec
-  d = ModifiedJulianDay wh
-  (wh, dec) = wholeDecimal n
+toTick n = Tick d t
+  where
+    t = dayFractionToTimeOfDay dec
+    d = ModifiedJulianDay wh
+    (wh, dec) = wholeDecimal n
 
 
-hourTick, halfHourTick, quarterHourTick :: Double
+hourTick, halfHourTick, quarterHourTick :: Rational
 hourTick = 1/24
 halfHourTick = 1/2 * hourTick
 quarterHourTick = 1/4 * hourTick
+
+
+-- locTime :: IO LocalTime
+-- locTime = do
+--   tz <- getCurrentTimeZone
+--   ct <- getCurrentTime
+--   return $ utcToLocalTime tz ct
 
 
 
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
@@ -26,16 +26,31 @@
 mkPoint :: a -> a -> Point a
 mkPoint = Point
 
--- | A binary operation on the components of two `Point`s
+-- | A binary operation on the components of two 'Point's
 lift2Point :: (a -> b -> c) -> Point a -> Point b -> Point c
 lift2Point f (Point a b) (Point c d) = Point (f a c) (f b d)
 
+-- | A unary operation on the components of a 'Point'
+lift1Point :: (a -> a -> b) -> Point a -> b
+lift1Point f (Point x y) = f x y
+
 pointInf, pointSup :: (Ord a) => Point a -> Point a -> Point a
 pointInf = lift2Point min
 pointSup = lift2Point max
 
+-- | The origin of the axes, point (0, 0)
+origin :: Num a => Point a
+origin = Point 0 0
 
+-- | The (1, 1) point
+oneOne :: Num a => Point a
+oneOne = Point 1 1
 
+-- | Cartesian distance from the origin
+norm2fromOrigin :: Floating a => Point a -> a
+norm2fromOrigin p = norm2 $ p -. origin
+
+
 -- | Overwrite either coordinate of a Point, to e.g. project on an axis
 setPointCoord :: Axis -> a -> Point a -> Point a
 setPointCoord axis c (Point x y)
@@ -90,7 +105,13 @@
 mkFrameOrigin :: Num a => a -> a -> Frame a
 mkFrameOrigin w h = Frame origin (Point w h)
 
+-- | The unit square (0, 0) - (1, 1)
+unitFrame :: Num a => Frame a
+unitFrame = mkFrame origin oneOne
 
+
+
+
 -- | Create a `Frame` from a container of `Point`s `P`, i.e. construct two points `p1` and `p2` such that :
 --
 -- p1 := inf(x,y) P
@@ -124,6 +145,42 @@
 
 
 
+
+-- | Interpolation
+
+interpolateBilinear :: Fractional a => Frame a -> Point a -> (Point a -> a) -> a
+interpolateBilinear (Frame q11@(Point x1 y1) q22@(Point x2 y2)) (Point x y) f =
+  let
+    q12 = Point x1 y2
+    q21 = Point x2 y1
+    fq11 = f q11
+    fq22 = f q22
+    fq12 = f q12
+    fq21 = f q21
+    den1 = (x1 - x2) * (y1 - y2)
+    den2 = (x1 - x2) * (y2 - y1)
+    c111 = fq11/den1
+    c112 = fq11/den2
+    c121 = fq12/den1
+    c122 = fq12/den2
+    c211 = fq21/den1
+    c212 = fq21/den2
+    c221 = fq22/den1
+    c222 = fq22/den2
+    a0 = c111 * x2 * y2 + c122 * x2 * y1 + c212 * x1 * y2 + c221 * x1 * y1
+    a1 = c112 * y2      + c121 * y1      + c211 * y2      + c222 * y1
+    a2 = c112 * x2      + c121 * x2      + c211 * x1      + c222 * x1
+    a3 = c111           + c122           + c212           + c221
+  in a0 + a1 * x + a2 * y + a3 * x * y
+
+
+
+
+
+
+
+
+
 -- * Axis
 
 data Axis = X | Y deriving (Eq, Show)
@@ -204,11 +261,9 @@
 v2fromEndpoints (Point px py) (Point qx qy) = V2 (qx-px) (qy-py)
 (-.) = v2fromEndpoints
 
--- | The origin of the axes, point (0, 0)
-origin :: Num a => Point a
-origin = Point 0 0
 
 
+
 -- | A Mat2 can be seen as a linear operator that acts on points in the plane
 data Mat2 a = Mat2 a a a a deriving (Eq, Show)
 
@@ -295,6 +350,10 @@
 
 
 
+
+
+
+
 -- | A list of `nx` by `ny` points in the plane arranged on the vertices of a rectangular mesh.
 --
 -- NB: Only the minimum x, y coordinate point is included in the output mesh. This is intentional, since the output from this can be used as an input to functions that use a corner rather than the center point as refernce (e.g. `rect`)
@@ -439,6 +498,12 @@
   
 instance Eps (V2 Float) where
   v1 ~= v2 = norm2 (v1 ^-^ v2) <= 1e-2
+
+
+
+
+
+
 
 
 
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
@@ -13,7 +13,7 @@
 
 import qualified Data.Colour as C
 import qualified Data.Colour.Names as C
-import Data.Colour.Palette.BrewerSet
+-- import Data.Colour.Palette.BrewerSet
 -- import Text.Blaze.Svg
 
 
diff --git a/src/Graphics/Rendering/Plot/Light/PlotTypes/Histogram.hs b/src/Graphics/Rendering/Plot/Light/PlotTypes/Histogram.hs
--- a/src/Graphics/Rendering/Plot/Light/PlotTypes/Histogram.hs
+++ b/src/Graphics/Rendering/Plot/Light/PlotTypes/Histogram.hs
@@ -5,7 +5,7 @@
 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.Palette.BrewerSet as CP
 import qualified Data.Colour.Names as C
 
 
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
@@ -8,7 +8,7 @@
 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.Palette.BrewerSet as CP
 import qualified Data.Colour.Names as C
 import qualified Data.Text as T
 
@@ -123,9 +123,9 @@
 glyph w sw Plus _ fcol p = plusGlyph w sw (fromMaybe C.black fcol) p
 
 
--- | 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 (pal, n) nsets = take nsets $ zip (cycle $ CP.brewerSet pal n ) (cycle [Square, Circle ..])
+-- -- | 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 (pal, n) nsets = take nsets $ zip (cycle $ CP.brewerSet pal n ) (cycle [Square, Circle ..])
 
 
 
