diff --git a/TestPlotly.hs b/TestPlotly.hs
deleted file mode 100644
--- a/TestPlotly.hs
+++ /dev/null
@@ -1,20 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-import Lucid
-import Lucid.Html5
-import Graphics.Plotly
-import Graphics.Plotly.Lucid
-import Lens.Micro
-
-import qualified Data.Text.Lazy as T
-import qualified Data.Text.Lazy.IO as T
-
-main = 
-  T.writeFile "test.html" $ renderText $ doctypehtml_ $ do
-    head_ $ do meta_ [charset_ "utf-8"]
-               plotlyCDN
-    body_ $ toHtml $ plotly "myDiv" [myTrace]                                                           
-
-myTrace = scatter & x ?~ [1,2,3,4]
-                  & y ?~ [500,3000,700,200]
-
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,10 @@
+0.1.1
+
+* Simple module to help build traces
+
+* remove test-plotly executable
+
+
 0.1
 
 * Initial release
diff --git a/plotlyhs.cabal b/plotlyhs.cabal
--- a/plotlyhs.cabal
+++ b/plotlyhs.cabal
@@ -1,5 +1,5 @@
 Name:                plotlyhs
-Version:             0.1.0
+Version:             0.2
 Synopsis:            Haskell bindings to Plotly.js
 Description:
             Generate web-based plots with the Plotly.js library.
@@ -11,9 +11,9 @@
 Author:              Tom Nielsen
 Maintainer:          tanielsen@gmail.com
 build-type:          Simple
-Cabal-Version: 	     >= 1.8
-homepage:            https://github.com/glutamate/plotlyhs
-bug-reports:         https://github.com/glutamate/plotlyhs/issues
+Cabal-Version: 	     >= 1.10
+homepage:            https://github.com/filopodia/open/plotlyhs
+bug-reports:         https://github.com/filopodia/open/issues
 category:            Graphics, Charts
 Tested-With:         GHC == 7.8.4, GHC == 7.10.2, GHC == 7.10.3, GHC == 8.0.1
 
@@ -24,18 +24,22 @@
 
 Library
    ghc-options:       -Wall -fno-warn-type-defaults
-   ghc-prof-options:  -auto-all
    hs-source-dirs:    src
+   default-language:  Haskell2010
 
+
    Exposed-modules:
                    Graphics.Plotly
                  , Graphics.Plotly.Utils
                  , Graphics.Plotly.Lucid
+                 , Graphics.Plotly.GoG
+                 , Graphics.Plotly.Base
                  , Graphics.Plotly.Blaze
                  , Graphics.Plotly.Histogram
+                 , Graphics.Plotly.Simple
 
    Build-depends:
-                 base                    >= 4.7
+                 base                    >= 4.6 && <5
                , aeson
                , lucid
                , blaze-html
@@ -44,12 +48,3 @@
                , bytestring
                , microlens-th
                , microlens
-
-executable test-plotly
-  main-is: TestPlotly.hs
-  build-depends:       base >=4.6 && <5
-                     , plotlyhs
-                     , lucid
-                     , aeson
-                     , text
-                     , microlens
diff --git a/src/Graphics/Plotly.hs b/src/Graphics/Plotly.hs
--- a/src/Graphics/Plotly.hs
+++ b/src/Graphics/Plotly.hs
@@ -2,253 +2,19 @@
 
 {-|
 
-This module defines datatypes that can be used to generate [Plotly.js](https://plot.ly/javascript/)
-plots via their JSON values. The interface encourages the use of
-lenses. Every trace on a plot is defined by a `Trace` type value, the
-construction of which is the central goal of this module.
-
-Example scatter plot of the Iris dataset:
-
-@
-import Graphics.Plotly
-import Numeric.Dataset.Iris
-
-tr :: Trace
-tr = scatter & x ?~ map sepalLength iris
-             & y ?~ map sepalWidth iris
-             & marker ?~ (defMarker & markercolor ?~ catColors (map irisClass irisd))
-             & mode ?~ [Markers]
-@
-
-Horizontal bars:
-
-@
-hbarData :: [(Text, Double)]
-hbarData = [(\"Simon\", 14.5), (\"Joe\", 18.9), (\"Dorothy\", 16.2)]
-
-hbarsTrace :: Trace
-hbarsTrace = bars & ytext ?~ map fst hbarData
-                  & x ?~ map snd hbarData
-                  & orientation ?~ Horizontal
-@
-
-see Graphics.Plotly.Lucid for helper functions that turn traces into HTML.
+Re-exports the Simple interface, the grammar of grpahics 
+interface and parts of the base interface.
 
 -}
 
-module Graphics.Plotly where
-
-import Data.Aeson
-import Data.Aeson.Types
-import Data.Char (toLower)
-import Data.List (intercalate, nub, findIndex)
-import Data.Monoid ((<>))
-import Data.Maybe (fromJust)
-import Data.Text (Text)
-
-import GHC.Generics
-import Lens.Micro.TH
-
-import Graphics.Plotly.Utils
-
--- * Traces
-
--- |How should traces be drawn? (lines or markers)
-data Mode = Markers | Lines deriving Show
-
-instance {-# OVERLAPS #-} ToJSON [Mode] where
-  toJSON = toJSON . intercalate "+" . map (map toLower . show)
-
--- | What kind of plot type are we building - scatter (inluding line plots) or bars?
-data TraceType = Scatter | Bar deriving Show
-
-instance ToJSON TraceType where
-  toJSON = toJSON . map toLower . show
-
-
--- | A color specification, either as a concrete RGB/RGBA value or a color per point.
-data Color = RGBA Int Int Int Int -- ^ use this RGBA color for every point in the trace
-           | RGB Int Int Int -- ^ use this RGB color for every point in the trace
-           | ColIxs [Int]  -- ^ use a different color index for each point
-           | Cols [Color] -- ^ use a different color for each point
-
-instance ToJSON Color where
-  toJSON (RGB r g b) = toJSON $ "rgb("<>show r<>","<>show g<>","<>show b<>")"
-  toJSON (RGBA r g b a) = toJSON $ "rgba("<>show r<>","<>show g<>","<>show b<>","<> show a<>")"
-  toJSON (ColIxs cs) = toJSON cs
-  toJSON (Cols cs) = toJSON cs
-
--- | Assign colors based on any categorical value
-catColors :: Eq a => [a] -> Color
-catColors xs =
-  let vals = nub xs
-      f x = fromJust $ findIndex (==x) vals
-  in ColIxs $ map f xs
-
--- | Different types of markers
-data Symbol = Circle | Square | Diamond | Cross deriving Show
-
-instance ToJSON Symbol where
-  toJSON = toJSON . map toLower . show
-
--- | Marker specification
-data Marker = Marker
-  { _size :: Maybe Int
-  , _markercolor :: Maybe Color
-  , _symbol :: Maybe Symbol
-  , _opacity :: Maybe Double
-  } deriving Generic
-
-makeLenses ''Marker
-
-instance ToJSON Marker where
-  toJSON = genericToJSON jsonOptions {fieldLabelModifier = rename "markercolor" "color" . unLens}
-
--- | default marker specification
-defMarker :: Marker
-defMarker  = Marker Nothing Nothing Nothing Nothing
-
-
--- | Dash type specification
-data Dash = Solid | Dashdot | Dot deriving Show
-
-instance ToJSON Dash where
-  toJSON = toJSON . map toLower . show
-
--- | Horizontal or Vertical orientation of bars
-data Orientation = Horizontal | Vertical
-
-instance ToJSON Orientation where
-  toJSON Horizontal = "h"
-  toJSON Vertical = "v"
-
--- | Are we filling area plots from the zero line or to the next Y value?
-data Fill = ToZeroY | ToNextY deriving Show
-
-instance ToJSON Fill where
-  toJSON = toJSON . map toLower . show
-
--- | line specification
-data Line = Line
-  { _linewidth :: Maybe Double
-  , _linecolor :: Maybe Color
-  , _dash :: Maybe Dash
-  } deriving Generic
-
-makeLenses ''Line
-
-instance ToJSON Line where
-  toJSON = genericToJSON jsonOptions { fieldLabelModifier = dropInitial "line" . unLens}
-
-defLine :: Line
-defLine = Line Nothing Nothing Nothing
-
--- | A `Trace` is the component of a plot. Multiple traces can be superimposed.
-data Trace = Trace
-  { _x :: Maybe [Double] -- ^ x values, as numbers
-  , _y :: Maybe [Double] -- ^ y values, as numbers
-  , _xtext :: Maybe [Text]  -- ^ x values, as Text
-  , _ytext :: Maybe [Text]  -- ^ y values, as Text
-  , _mode :: Maybe [Mode] -- ^ select one or two modes.
-  , _name :: Maybe Text -- ^ name of this trace, for legend
-  , _text :: Maybe [Text]
-  , _tracetype :: TraceType
-  , _marker :: Maybe Marker
-  , _line :: Maybe Line
-  , _fill :: Maybe Fill
-  , _orientation :: Maybe Orientation
-  } deriving Generic
-
-makeLenses ''Trace
-
--- |an empty scatter plot
-scatter :: Trace
-scatter = Trace Nothing Nothing Nothing Nothing Nothing Nothing Nothing Scatter Nothing Nothing Nothing Nothing
-
--- |an empty bar plot
-bars :: Trace
-bars = Trace Nothing Nothing Nothing Nothing Nothing Nothing Nothing Bar Nothing Nothing Nothing Nothing
-
-
-instance ToJSON Trace where
-  toJSON = genericToJSON jsonOptions {fieldLabelModifier = rename "tracetype" "type" . rename "xtext" "x" . rename "ytext" "y" . unLens}
-
--- |Options for axes
-data Axis = Axis
-  { _range :: Maybe (Double,Double)
-  , _axistitle :: Maybe Text
-  , _showgrid :: Maybe Bool
-  , _zeroline :: Maybe Bool
-  } deriving Generic
-
-makeLenses ''Axis
-
-instance ToJSON Axis where
-  toJSON = genericToJSON jsonOptions {fieldLabelModifier = rename "axistitle" "axis" . unLens}
-
-defAxis :: Axis
-defAxis = Axis Nothing Nothing Nothing Nothing
-
--- * Layouts
-
--- | How different bar traces be superimposed? By grouping or by stacking?
-data Barmode = Stack | Group deriving Show
-
-instance ToJSON Barmode where
-  toJSON = toJSON . map toLower . show
-
--- |Options for Margins.
-data Margin = Margin
-  { _marginl :: Int
-  , _marginr :: Int
-  , _marginb :: Int
-  , _margint :: Int
-  , _marginpad :: Int
-  } deriving Generic
-
-makeLenses ''Margin
-
-instance ToJSON Margin where
-  toJSON = genericToJSON jsonOptions { fieldLabelModifier = dropInitial "margin" . unLens}
-
--- | some good values for margins
-thinMargins, titleMargins :: Margin
-thinMargins = Margin 50 25 30 10 4
-titleMargins = Margin 50 25 30 40 4
-
-
--- |options for the layout of the whole plot
-data Layout = Layout
-  { _xaxis :: Maybe Axis
-  , _yaxis :: Maybe Axis
-  , _title :: Maybe Text
-  , _showlegend :: Maybe Bool
-  , _height :: Maybe Int
-  , _width :: Maybe Int
-  , _barmode :: Maybe Barmode
-  , _margin :: Maybe Margin
-  } deriving Generic
-
-makeLenses ''Layout
-
--- |a defaultlayout
-defLayout :: Layout
-defLayout = Layout Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
-
-instance ToJSON Layout where
-  toJSON = genericToJSON jsonOptions
-
--- * Plotly
-
--- | A helper record which represents the whole plot
-data Plotly = Plotly
-  { _elemid :: Text
-  , _traces :: [Trace]
-  , _layout :: Layout
-  }
+module Graphics.Plotly (
+  module Base,
+  module Simple,
+  module GoG
+) where
 
-makeLenses ''Plotly
+import Graphics.Plotly.Base as Base 
+  hiding (x,y, _x, _y, _size, _line, size, line)
+import Graphics.Plotly.Simple as Simple
+import Graphics.Plotly.GoG as GoG
 
--- | helper function for building the plot.
-plotly :: Text -> [Trace] -> Plotly
-plotly idnm trs = Plotly idnm trs defLayout
diff --git a/src/Graphics/Plotly/Base.hs b/src/Graphics/Plotly/Base.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Plotly/Base.hs
@@ -0,0 +1,256 @@
+{-# LANGUAGE DeriveGeneric, OverloadedStrings,FlexibleInstances, TemplateHaskell #-}
+
+{-|
+
+This module defines datatypes that can be used to generate [Plotly.js](https://plot.ly/javascript/)
+plots via their JSON values. The interface encourages the use of
+lenses. Every trace on a plot is defined by a `Trace` type value, the
+construction of which is the central goal of this module.
+
+Example scatter plot of the Iris dataset:
+
+@
+import Graphics.Plotly
+import Numeric.Dataset.Iris
+
+tr :: Trace
+tr = scatter & x ?~ map sepalLength iris
+             & y ?~ map sepalWidth iris
+             & marker ?~ (defMarker & markercolor ?~ catColors (map irisClass irisd))
+             & mode ?~ [Markers]
+@
+
+Horizontal bars:
+
+@
+hbarData :: [(Text, Double)]
+hbarData = [(\"Simon\", 14.5), (\"Joe\", 18.9), (\"Dorothy\", 16.2)]
+
+hbarsTrace :: Trace
+hbarsTrace = bars & ytext ?~ map fst hbarData
+                  & x ?~ map snd hbarData
+                  & orientation ?~ Horizontal
+@
+
+see Graphics.Plotly.Lucid for helper functions that turn traces into HTML.
+
+-}
+
+module Graphics.Plotly.Base where
+
+import Data.Aeson
+import Data.Aeson.Types
+import Data.Char (toLower)
+import Data.List (intercalate, nub, findIndex)
+import Data.Monoid ((<>))
+import Data.Maybe (fromJust)
+import Data.Text (Text)
+
+import GHC.Generics
+import Lens.Micro.TH
+
+import Graphics.Plotly.Utils
+
+-- * Traces
+
+-- |How should traces be drawn? (lines or markers)
+data Mode = Markers | Lines deriving Show
+
+instance {-# OVERLAPS #-} ToJSON [Mode] where
+  toJSON = toJSON . intercalate "+" . map (map toLower . show)
+
+-- | What kind of plot type are we building - scatter (inluding line plots) or bars?
+data TraceType = Scatter | Bar deriving Show
+
+instance ToJSON TraceType where
+  toJSON = toJSON . map toLower . show
+
+
+-- | A color specification, either as a concrete RGB/RGBA value or a color per point.
+data Color = ColRGBA Int Int Int Int -- ^ use this RGBA color for every point in the trace
+           | ColRGB Int Int Int -- ^ use this RGB color for every point in the trace
+           | ColIx Int  -- ^ use a different color index for each point
+
+instance ToJSON Color where
+  toJSON (ColRGB r g b) = toJSON $ "rgb("<>show r<>","<>show g<>","<>show b<>")"
+  toJSON (ColRGBA r g b a) = toJSON $ "rgba("<>show r<>","<>show g<>","<>show b<>","<> show a<>")"
+  toJSON (ColIx cs) = toJSON cs
+
+-- | Assign colors based on any categorical value
+catColors :: Eq a => [a] -> ListOrElem Value
+catColors xs =
+  let vals = nub xs
+      f x = fromJust $ findIndex (==x) vals
+  in List $ map (toJSON . ColIx . f) xs
+
+-- | Different types of markers
+data Symbol = Circle | Square | Diamond | Cross deriving (Show, Eq)
+
+instance ToJSON Symbol where
+  toJSON = toJSON . map toLower . show
+
+data ListOrElem a = List [a] | All a deriving Eq
+
+instance ToJSON a => ToJSON (ListOrElem a) where
+  toJSON (List xs) = toJSON xs
+  toJSON (All x) = toJSON x
+
+-- | Marker specification
+data Marker = Marker
+  { _size :: Maybe (ListOrElem Value)
+  , _markercolor :: Maybe (ListOrElem Value)
+  , _symbol :: Maybe Symbol
+  , _opacity :: Maybe Double
+  } deriving (Generic, Eq)
+
+makeLenses ''Marker
+
+instance ToJSON Marker where
+  toJSON = genericToJSON jsonOptions {fieldLabelModifier = rename "markercolor" "color" . unLens}
+
+-- | default marker specification
+defMarker :: Marker
+defMarker  = Marker Nothing Nothing Nothing Nothing
+
+
+-- | Dash type specification
+data Dash = Solid | Dashdot | Dot deriving Show
+
+instance ToJSON Dash where
+  toJSON = toJSON . map toLower . show
+
+-- | Horizontal or Vertical orientation of bars
+data Orientation = Horizontal | Vertical
+
+instance ToJSON Orientation where
+  toJSON Horizontal = "h"
+  toJSON Vertical = "v"
+
+-- | Are we filling area plots from the zero line or to the next Y value?
+data Fill = ToZeroY | ToNextY deriving Show
+
+instance ToJSON Fill where
+  toJSON = toJSON . map toLower . show
+
+-- | line specification
+data Line = Line
+  { _linewidth :: Maybe Double
+  , _linecolor :: Maybe Color
+  , _dash :: Maybe Dash
+  } deriving Generic
+
+makeLenses ''Line
+
+instance ToJSON Line where
+  toJSON = genericToJSON jsonOptions { fieldLabelModifier = dropInitial "line" . unLens}
+
+defLine :: Line
+defLine = Line Nothing Nothing Nothing
+
+-- | A `Trace` is the component of a plot. Multiple traces can be superimposed.
+data Trace = Trace
+  { _x :: Maybe [Value] -- ^ x values, as numbers
+  , _y :: Maybe [Value] -- ^ y values, as numbers
+  , _mode :: Maybe [Mode] -- ^ select one or two modes.
+  , _name :: Maybe Text -- ^ name of this trace, for legend
+  , _text :: Maybe [Text]
+  , _tracetype :: TraceType
+  , _marker :: Maybe Marker
+  , _line :: Maybe Line
+  , _fill :: Maybe Fill
+  , _orientation :: Maybe Orientation
+  } deriving Generic
+
+makeLenses ''Trace
+
+-- |an empty scatter plot
+scatter :: Trace
+scatter = Trace Nothing Nothing Nothing Nothing Nothing Scatter Nothing Nothing Nothing Nothing
+
+-- |an empty bar plot
+bars :: Trace
+bars = Trace Nothing Nothing Nothing Nothing Nothing Bar Nothing Nothing Nothing Nothing
+
+
+instance ToJSON Trace where
+  toJSON = genericToJSON jsonOptions {fieldLabelModifier = rename "tracetype" "type" . unLens}
+
+-- |Options for axes
+data Axis = Axis
+  { _range :: Maybe (Double,Double)
+  , _axistitle :: Maybe Text
+  , _showgrid :: Maybe Bool
+  , _zeroline :: Maybe Bool
+  } deriving Generic
+
+makeLenses ''Axis
+
+instance ToJSON Axis where
+  toJSON = genericToJSON jsonOptions {fieldLabelModifier = rename "axistitle" "axis" . unLens}
+
+defAxis :: Axis
+defAxis = Axis Nothing Nothing Nothing Nothing
+
+-- * Layouts
+
+-- | How different bar traces be superimposed? By grouping or by stacking?
+data Barmode = Stack | Group deriving Show
+
+instance ToJSON Barmode where
+  toJSON = toJSON . map toLower . show
+
+-- |Options for Margins.
+data Margin = Margin
+  { _marginl :: Int
+  , _marginr :: Int
+  , _marginb :: Int
+  , _margint :: Int
+  , _marginpad :: Int
+  } deriving Generic
+
+makeLenses ''Margin
+
+instance ToJSON Margin where
+  toJSON = genericToJSON jsonOptions { fieldLabelModifier = dropInitial "margin" . unLens}
+
+-- | some good values for margins
+thinMargins, titleMargins :: Margin
+thinMargins = Margin 50 25 30 10 4
+titleMargins = Margin 50 25 30 40 4
+
+
+-- |options for the layout of the whole plot
+data Layout = Layout
+  { _xaxis :: Maybe Axis
+  , _yaxis :: Maybe Axis
+  , _title :: Maybe Text
+  , _showlegend :: Maybe Bool
+  , _height :: Maybe Int
+  , _width :: Maybe Int
+  , _barmode :: Maybe Barmode
+  , _margin :: Maybe Margin
+  } deriving Generic
+
+makeLenses ''Layout
+
+-- |a defaultlayout
+defLayout :: Layout
+defLayout = Layout Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
+
+instance ToJSON Layout where
+  toJSON = genericToJSON jsonOptions
+
+-- * Plotly
+
+-- | A helper record which represents the whole plot
+data Plotly = Plotly
+  { _elemid :: Text
+  , _traces :: [Trace]
+  , _layout :: Layout
+  }
+
+makeLenses ''Plotly
+
+-- | helper function for building the plot.
+plotly :: Text -> [Trace] -> Plotly
+plotly idnm trs = Plotly idnm trs defLayout
diff --git a/src/Graphics/Plotly/Blaze.hs b/src/Graphics/Plotly/Blaze.hs
--- a/src/Graphics/Plotly/Blaze.hs
+++ b/src/Graphics/Plotly/Blaze.hs
@@ -21,7 +21,7 @@
 import Text.Blaze
 import qualified Text.Blaze.Html5 as H
 import qualified Text.Blaze.Html5.Attributes as A
-import Graphics.Plotly
+import Graphics.Plotly.Base
 import Data.Monoid ((<>))
 import Data.Text.Encoding (decodeUtf8)
 import Data.ByteString.Lazy (toStrict)
diff --git a/src/Graphics/Plotly/GoG.hs b/src/Graphics/Plotly/GoG.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Plotly/GoG.hs
@@ -0,0 +1,128 @@
+{-# LANGUAGE OverloadedStrings, FlexibleInstances, TypeFamilies, FlexibleContexts #-}
+
+{-|
+A limited Grammar of Graphics-like interface.
+
+@
+myPts :: [(Double, Double)]
+myPts = [(1,2), (1.2, 3), (1.4,3.5)]
+
+
+
+myTrace :: Trace
+myTrace = points (aes & x .~ fst
+                      & y .~ snd)
+                 myPts
+@
+
+
+
+-}
+
+module Graphics.Plotly.GoG where
+
+import qualified Graphics.Plotly.Base as Plot
+import Data.Text (Text)
+import Lens.Micro
+import Data.Aeson
+
+class ToJSON a => AxisValue a
+
+instance AxisValue Double
+instance AxisValue Float
+instance AxisValue Text
+instance AxisValue String
+instance AxisValue Int
+
+data RGB a = RGB a a a
+data RGBA a = RGBA a a a a
+
+instance ToJSON (RGB Int) where
+  toJSON (RGB r g b) = toJSON $ concat ["rgb(",show r,",",show g, ",", show b,")"]
+
+instance ToJSON (RGB Double) where
+  toJSON (RGB r g b) = toJSON $ concat ["rgb(",showd r,",",showd g, ",", showd b,")"]
+   where showd = show . floor . (*256)
+
+instance ToJSON (RGBA Int) where
+  toJSON (RGBA r g b a) = toJSON $ concat ["rgba(",show r,",",show g, ",", show b,",", show a, ")"]
+
+instance ToJSON (RGBA Double) where
+  toJSON (RGBA r g b a) = toJSON $ concat ["rgb(",showd r,",",showd g, ",", showd b,",", showd a,")"]
+   where showd = show . floor . (*256)
+
+class ToJSON a => IsColor a
+
+instance IsColor Int
+instance IsColor (RGB Int)
+instance IsColor (RGB Double)
+instance IsColor (RGBA Int)
+instance IsColor (RGBA Double)
+
+type family XVal a
+type family YVal a
+type family CVal a
+type family SVal a
+
+type instance XVal (x,y,c,s) = x
+type instance YVal (x,y,c,s) = y
+type instance CVal (x,y,c,s) = c
+type instance SVal (x,y,c,s) = s
+
+data Aes t a = Aes { _x :: (a -> XVal t)
+                   , _y :: (a -> YVal t)
+                   , _color :: Maybe (a -> CVal t)
+                   , _size :: Maybe (a -> SVal t)
+                   }
+aes :: Aes ((), (), (), ()) a
+aes = Aes (const ()) (const ()) Nothing Nothing
+
+setx :: AxisValue v => Aes (vx,vy,vc,vs) a -> (a -> v) -> Aes (v, vy, vc, vs) a
+setx (Aes _ fy fc fs) f = (Aes f fy fc fs)
+
+x :: AxisValue v => Lens (Aes (vx,vy, vc, vs) a) (Aes (v,vy, vc, vs) a) (a -> vx) (a -> v)
+x = lens _x setx
+
+sety :: AxisValue v => Aes (vx,vy, vc, vs) a -> (a -> v) -> Aes (vx, v, vc, vs) a
+sety (Aes fx _ fc fs) f = (Aes fx f fc fs)
+
+y :: AxisValue v => Lens (Aes (vx,vy, vc, vs) a) (Aes (vx,v, vc, vs) a) (a -> vy) (a -> v)
+y = lens _y sety
+
+setcol :: IsColor v => Aes (vx,vy, vc, vs) a -> Maybe (a -> v) -> Aes (vx, vy, v, vs) a
+setcol (Aes fx fy _ fs) f = (Aes fx fy f fs)
+
+color :: IsColor v => Lens (Aes (vx,vy, vc, vs) a) (Aes (vx,vy,v,vs) a) (Maybe (a -> vc)) (Maybe (a -> v))
+color = lens _color setcol
+
+setsize :: (AxisValue v, Num v) => Aes (vx,vy, vc, vs) a -> Maybe (a -> v) -> Aes (vx, vy, vc, v) a
+setsize (Aes fx fy fc _) f = (Aes fx fy fc f)
+
+size :: (AxisValue v, Num v) => Lens (Aes (vx,vy, vc, vs) a) (Aes (vx,vy,vc,v) a) (Maybe (a -> vs)) (Maybe (a -> v))
+size = lens _size setsize
+
+
+points :: (AxisValue (XVal t), AxisValue (YVal t), Num (XVal t), Num (YVal t), ToJSON (CVal t), ToJSON (SVal t))
+       => Aes t a -> [a] -> Plot.Trace
+points a xs =  setSize (_size a) $ setColors (_color a) $ Plot.scatter
+                 & Plot.x ?~ map (toJSON . _x a) xs
+                 & Plot.y ?~ map (toJSON . _y a) xs
+                 & Plot.mode ?~ [Plot.Markers]
+  where setColors Nothing p = p
+        setColors (Just setC) p
+          = p & Plot.marker . non Plot.defMarker . Plot.markercolor ?~ Plot.List (map (toJSON . setC) xs)
+        setSize Nothing p = p
+        setSize (Just setS) p
+          = p & Plot.marker . non Plot.defMarker . Plot.size ?~ Plot.List (map (toJSON . setS) xs)
+
+line :: (AxisValue (XVal t), AxisValue (YVal t), Num (XVal t), Num (YVal t))
+       => Aes t a -> [a] -> Plot.Trace
+line a xs = Plot.scatter & Plot.x ?~ map (toJSON . _x a) xs
+                 & Plot.y ?~ map (toJSON . _y a) xs
+                 & Plot.mode ?~ [Plot.Lines]
+
+hbars :: (AxisValue (XVal t), AxisValue (YVal t), Num (XVal t))
+       => Aes t a -> [a] -> Plot.Trace
+hbars a xs = Plot.bars & Plot.x ?~ map (toJSON . _x a) xs
+                 & Plot.y ?~ map (toJSON . _y a) xs
+                 & Plot.orientation ?~ Plot.Horizontal
diff --git a/src/Graphics/Plotly/Histogram.hs b/src/Graphics/Plotly/Histogram.hs
--- a/src/Graphics/Plotly/Histogram.hs
+++ b/src/Graphics/Plotly/Histogram.hs
@@ -6,9 +6,10 @@
 
 module Graphics.Plotly.Histogram where
 
-import Graphics.Plotly
+import Graphics.Plotly.Base
 import Data.List (sort, group)
 import Lens.Micro
+import Data.Aeson (toJSON)
 
 -- | build a histogram with a given binsize
 histogram :: Int -- ^ number of bins
@@ -18,13 +19,15 @@
   let (lo, hi) = (minimum pts, maximum pts)
       binSize = (hi - lo) / realToFrac nbins
       binf :: Double -> Int
-      binf x = floor $ (x - lo) / binSize
+      binf xv = floor $ (xv - lo) / binSize
+      binToX :: Int -> Double
       binToX binN = realToFrac binN * binSize + lo
       bins = group $ sort $ map binf pts
-      goFill (car@(bin1,count1):cdr@((bin2,count2):_))
+      goFill (car@(bin1,_):cdr@((bin2,_):_))
          | bin2 == bin1 + 1 =  car : goFill cdr
          | otherwise = car : goFill ((bin1+1,0):cdr)
       goFill l = l
+      binMap :: [(Int, Int)]
       binMap = goFill $ map (\is -> (head is, length is)) bins
 
-  in bars & x ?~ map (binToX . fst) binMap & y ?~ map (realToFrac . snd) binMap
+  in bars & x ?~ map (toJSON . binToX . fst) binMap & y ?~ map (toJSON .  snd) binMap
diff --git a/src/Graphics/Plotly/Lucid.hs b/src/Graphics/Plotly/Lucid.hs
--- a/src/Graphics/Plotly/Lucid.hs
+++ b/src/Graphics/Plotly/Lucid.hs
@@ -19,7 +19,7 @@
 module Graphics.Plotly.Lucid where
 
 import Lucid
-import Graphics.Plotly
+import Graphics.Plotly.Base
 import Data.Monoid ((<>))
 import Data.Text.Encoding (decodeUtf8)
 import Data.ByteString.Lazy (toStrict)
diff --git a/src/Graphics/Plotly/Simple.hs b/src/Graphics/Plotly/Simple.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Plotly/Simple.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+{-|
+
+Functions to build Traces from standard data. Generated traces can still be customized with lenses
+
+-}
+
+module Graphics.Plotly.Simple where
+
+import Graphics.Plotly.Base
+import Lens.Micro
+import Data.Text (Text)
+import Data.Aeson
+
+
+-- |Generate a scatterplot from pairs
+scatterPlot :: [(Double,Double)] -> Trace
+scatterPlot xys = scatter & x ?~ map (toJSON .fst) xys
+                          & y ?~ map (toJSON .snd) xys
+                          & mode ?~ [Markers]
+-- |Generate a line plot from pairs
+linePlot :: [(Double,Double)] -> Trace
+linePlot xys    = scatter & x ?~ map (toJSON .fst) xys
+                          & y ?~ map (toJSON .snd) xys
+                          & mode ?~ [Lines]
+
+-- |Generate a horizontal bar chart from pairs of text and value.
+hbarChart :: [(Text, Double)] -> Trace
+hbarChart tvs = bars & y ?~ map (toJSON . fst) tvs
+                     & x ?~ map (toJSON .snd) tvs
+                     & orientation ?~ Horizontal
+
+-- |Generate a fan plot with a given width in standard deviations and
+--  (x,(y,sd)) data
+fanPlot :: Double -> [(Double, (Double, Double))] -> Trace
+fanPlot sdCount tmnsds =
+  let xs = map fst tmnsds ++ reverse (map fst tmnsds)
+      ys = map ((\(m,sd) -> m+sdCount*sd) . snd) tmnsds
+           ++ reverse ( map ((\(m,sd) -> m-sdCount*sd) . snd) tmnsds)
+  in  scatter & x ?~ map toJSON xs & y ?~ map toJSON ys & fill ?~ ToZeroY
