diff --git a/gnuplot.cabal b/gnuplot.cabal
--- a/gnuplot.cabal
+++ b/gnuplot.cabal
@@ -1,5 +1,5 @@
 Name:             gnuplot
-Version:          0.4.2
+Version:          0.5
 License:          BSD3
 License-File:     LICENSE
 Author:           Henning Thielemann <haskell@henning-thielemann.de>
@@ -45,7 +45,7 @@
   data/runtime.data
 
 Source-Repository this
-  Tag:         0.4.2
+  Tag:         0.5
   Type:        darcs
   Location:    http://code.haskell.org/gnuplot/
 
@@ -74,14 +74,14 @@
 
 Library
   Build-Depends:
-    array >= 0.1 && <0.4,
+    array >= 0.1 && <0.5,
     containers >= 0.1 && <0.5,
     utility-ht >= 0.0.1 && < 0.1,
     monoid-transformer >= 0.0.2 && <0.1
   If flag(splitBase)
     Build-Depends:
-      process >= 1.0 && < 1.1,
-      time >= 1.1 && < 1.3,
+      process >= 1.0 && < 1.2,
+      time >= 1.1 && < 1.5,
       old-locale >= 1.0 && < 1.1,
       base >= 2 && <5
   Else
@@ -103,13 +103,18 @@
     Graphics.Gnuplot.Simple
     Graphics.Gnuplot.Time
     Graphics.Gnuplot.Advanced
+    Graphics.Gnuplot.Display
+    Graphics.Gnuplot.Terminal
     Graphics.Gnuplot.Terminal.PostScript
     Graphics.Gnuplot.Terminal.PNG
     Graphics.Gnuplot.Terminal.SVG
+    Graphics.Gnuplot.Terminal.WXT
     Graphics.Gnuplot.Terminal.X11
     Graphics.Gnuplot.Frame
     Graphics.Gnuplot.Frame.Option
     Graphics.Gnuplot.Frame.OptionSet
+    Graphics.Gnuplot.Frame.OptionSet.Style
+    Graphics.Gnuplot.Frame.OptionSet.Histogram
     Graphics.Gnuplot.Plot.TwoDimensional
     Graphics.Gnuplot.Plot.ThreeDimensional
     Graphics.Gnuplot.Graph
@@ -134,10 +139,10 @@
     Graphics.Gnuplot.Private.Graph2DType
     Graphics.Gnuplot.Private.Graph3DType
     Graphics.Gnuplot.Private.GraphEmpty
+    Graphics.Gnuplot.Private.Terminal
+    Graphics.Gnuplot.Private.Display
     Graphics.Gnuplot.Utility
     Graphics.Gnuplot.Execute
-    Graphics.Gnuplot.Display
-    Graphics.Gnuplot.Terminal
 
 Executable gnuplot-demo
   If flag(buildExamples)
diff --git a/src/Demo.hs b/src/Demo.hs
--- a/src/Demo.hs
+++ b/src/Demo.hs
@@ -6,8 +6,9 @@
 import qualified Graphics.Gnuplot.MultiPlot as MultiPlot
 
 import qualified Graphics.Gnuplot.Frame as Frame
-import qualified Graphics.Gnuplot.Frame.Option as Opt
 import qualified Graphics.Gnuplot.Frame.OptionSet as Opts
+import qualified Graphics.Gnuplot.Frame.OptionSet.Style as OptsStyle
+import qualified Graphics.Gnuplot.Frame.OptionSet.Histogram as Histogram
 
 import qualified Graphics.Gnuplot.Graph as Graph
 
@@ -53,11 +54,33 @@
 
 overlay2d :: Frame.T (Graph2D.T Double Double)
 overlay2d =
-   Frame.cons (Opts.size 1 0.4 $ Opts.remove Opt.key $ Opts.deflt) $
+   Frame.cons (Opts.size 1 0.4 $ Opts.key False $ Opts.deflt) $
    Plot2D.function Graph2D.lines (linearScale 100 (-pi,pi)) cos
    `mappend`
    circle2d
 
+histogram2d :: Frame.T (Graph2D.T Int Double)
+histogram2d =
+   Frame.cons (
+      Opts.title "Comparison of how well software revisions perform on each hardware version" $
+      Histogram.clusteredGap 2 $
+      Opts.boxwidthAbsolute 0.9 $
+      OptsStyle.fillBorderLineType (-1) $
+      OptsStyle.fillSolid $
+      Opts.xTicks2d
+         [("220", 0), ("320", 1), ("420", 2), ("520", 3), ("620", 4), ("720", 5)] $
+      Opts.yRange2d (0,3000) $
+      Opts.deflt) $
+   mconcat $
+   map (\(title,dat) ->
+      fmap (Graph2D.lineSpec (LineSpec.title title LineSpec.deflt)) $
+      Plot2D.list Graph2D.histograms dat) $
+   ("1.0011", [102, 213, 378, 408, 840,  920]) :
+   ("1.0012", [152, 233, 388, 433, 850, 1200]) :
+   ("1.0013", [172, 263, 408, 463, 860, 1500]) :
+   ("1.0014", [192, 293, 458, 483, 890, 2000]) :
+   []
+
 names2d ::
    Frame.T (Graph2D.T Double Double)
 names2d =
@@ -98,7 +121,7 @@
    listArray ((0::Int,0::Int), (0,2)) $
    MultiPlot.partFromPlot circle2d :
    MultiPlot.partFromFrame
-      (Frame.cons (Opts.xFormat "%m-%d" $ Opts.remove Opt.key $ Opts.deflt) $
+      (Frame.cons (Opts.xFormat "%m-%d" $ Opts.key False $ Opts.deflt) $
        candle2d) :
    MultiPlot.partFromPlot list2d :
    []
@@ -113,14 +136,14 @@
    listArray ((0::Int,0::Int), (0,2)) $
    MultiPlot.partFromPlot candle2d :
    MultiPlot.partFromFrame
-      (Frame.cons (Opts.yLabel "Fibonacci" $ Opts.remove Opt.key $ Opts.deflt)
+      (Frame.cons (Opts.yLabel "Fibonacci" $ Opts.key False $ Opts.deflt)
        list2d) :
    MultiPlot.partFromPlot candle2d :
    []
 
 defltOpts :: Graph.C graph => Opts.T graph
 defltOpts =
-   Opts.remove Opt.key $
+   Opts.key False $
    Opts.deflt
 
 wave3d :: Frame.T (Graph3D.T Double Double Double)
@@ -151,7 +174,8 @@
 -}
        center =
           MultiPlot.partFromFrame wave3d
-   in  MultiPlot.simpleFromPartArray $
+   in  MultiPlot.title "multiplot of 2d and 3d graphics" $
+       MultiPlot.simpleFromPartArray $
        listArray ((0::Int,0::Int), (2,4)) $
        prefix ++ center : suffix
 
@@ -161,6 +185,7 @@
    Plot.plot X11.cons simple2d :
    Plot.plot X11.cons list2d :
    Plot.plot X11.cons candle2d :
+   Plot.plot X11.cons histogram2d :
    Plot.plot X11.cons names2d :
    Plot.plot X11.cons overlay2d :
    (Plot.plot X11.cons . flip file2d "runtime.data"
diff --git a/src/Graphics/Gnuplot/Advanced.hs b/src/Graphics/Gnuplot/Advanced.hs
--- a/src/Graphics/Gnuplot/Advanced.hs
+++ b/src/Graphics/Gnuplot/Advanced.hs
@@ -74,9 +74,9 @@
   ) where
 
 import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet
-import qualified Graphics.Gnuplot.Display as Display
+import qualified Graphics.Gnuplot.Private.Display as Display
 
-import qualified Graphics.Gnuplot.Terminal as Terminal
+import qualified Graphics.Gnuplot.Private.Terminal as Terminal
 import qualified Graphics.Gnuplot.Execute as Exec
 
 import System.Exit (ExitCode, )
diff --git a/src/Graphics/Gnuplot/Display.hs b/src/Graphics/Gnuplot/Display.hs
--- a/src/Graphics/Gnuplot/Display.hs
+++ b/src/Graphics/Gnuplot/Display.hs
@@ -1,59 +1,7 @@
 {- |
-This class allows gives a uniform interface to plotting
+This class gives a uniform interface to plotting
 @Plot@, @Frame@ and @MultiPlot@.
 -}
-module Graphics.Gnuplot.Display where
-
-import qualified Graphics.Gnuplot.Private.FrameOption as Option
-
-import qualified Data.Map as Map
-import qualified Data.Monoid.State as State
-import Data.Monoid (Monoid, mempty, mappend, )
-
-
--- * User front-end
-
-newtype Script =
-   Script {
-      runScript :: State.T (Int, OptionSet) Body
-   }
-
-data Body =
-   Body {
-      files :: [File],
-      commands :: [String]
-   }
-
-type OptionSet = Map.Map Option.T [String]
-
-data File =
-   File {
-      filename :: FilePath,
-      content :: String
-   }
-
-writeData :: File -> IO ()
-writeData (File fn cont) =
-   writeFile fn cont
-
-
-{-
-Could also be implemented with Control.Monad.Trans.State:
-mappend = liftA2 mappend
--}
-instance Monoid Script where
-   mempty = Script mempty
-   mappend (Script b0) (Script b1) =
-      Script (mappend b0 b1)
-
-{-
-Could also be implemented with Control.Monad.Trans.State:
-mappend = liftA2 mappend
--}
-instance Monoid Body where
-   mempty = Body mempty mempty
-   mappend (Body f0 c0) (Body f1 c1) =
-      Body (mappend f0 f1) (mappend c0 c1)
+module Graphics.Gnuplot.Display (C, ) where
 
-class C gfx where
-   toScript :: gfx -> Script
+import Graphics.Gnuplot.Private.Display
diff --git a/src/Graphics/Gnuplot/Frame/Option.hs b/src/Graphics/Gnuplot/Frame/Option.hs
--- a/src/Graphics/Gnuplot/Frame/Option.hs
+++ b/src/Graphics/Gnuplot/Frame/Option.hs
@@ -1,9 +1,38 @@
 module Graphics.Gnuplot.Frame.Option (
-   Option.T,
-   module Graphics.Gnuplot.Private.FrameOption,
+   -- hide Cons constructor
+   T,
+
+   custom,
+
+   title,
+   grid,
+   size,
+   key,
+   border,
+   pm3d,
+   view,
+
+   xRange,
+   yRange,
+   zRange,
+
+   xLabel,
+   yLabel,
+   zLabel,
+
+   xTicks,
+   yTicks,
+   zTicks,
+
+   xData,
+   yData,
+   zData,
+
+   xFormat,
+   yFormat,
+   zFormat,
+
+   timeFmt,
    ) where
 
--- exclude Cons constructor
--- this does not work, Cons is exported anyway
-import Graphics.Gnuplot.Private.FrameOption hiding (T)
-import qualified Graphics.Gnuplot.Private.FrameOption as Option
+import Graphics.Gnuplot.Private.FrameOption
diff --git a/src/Graphics/Gnuplot/Frame/OptionSet.hs b/src/Graphics/Gnuplot/Frame/OptionSet.hs
--- a/src/Graphics/Gnuplot/Frame/OptionSet.hs
+++ b/src/Graphics/Gnuplot/Frame/OptionSet.hs
@@ -7,6 +7,7 @@
 
    size,
    title,
+   key,
    xRange2d,
    yRange2d,
    xRange3d,
@@ -15,12 +16,20 @@
    xLabel,
    yLabel,
    zLabel,
+   xTicks2d,
+   yTicks2d,
+   xTicks3d,
+   yTicks3d,
+   zTicks3d,
    xFormat,
    yFormat,
    zFormat,
 
    view,
    viewMap,
+
+   boxwidthRelative,
+   boxwidthAbsolute,
    ) where
 
 
@@ -36,22 +45,25 @@
 
 import Graphics.Gnuplot.Private.FrameOptionSet (T, )
 
-import Graphics.Gnuplot.Utility
-   (quote, )
+import Graphics.Gnuplot.Utility (quote, )
 
+import qualified Data.List as List
 
+
 deflt :: Graph.C graph => T graph
 deflt = Graph.defltOptions
 
 
 size :: Graph.C graph => Double -> Double -> T graph -> T graph
 size x y =
-   OptionSet.add Option.size [show x ++ ", " ++ show y]
+   OptionSet.add Option.sizeScale [show x ++ ", " ++ show y]
 
 title :: Graph.C graph => String -> T graph -> T graph
 title text =
    OptionSet.add Option.title [quote text]
 
+key :: Graph.C graph => Bool -> T graph -> T graph
+key = OptionSet.boolean Option.keyShow
 
 {-
 xRange :: Graph.C graph => (Double, Double) -> T graph -> T graph
@@ -67,28 +79,28 @@
 xRange2d ::
    (Atom.C x, Atom.C y, Tuple.C x) =>
    (x, x) -> T (Graph2D.T x y) -> T (Graph2D.T x y)
-xRange2d = range Option.xRange
+xRange2d = range Option.xRangeBounds
 
 yRange2d ::
    (Atom.C x, Atom.C y, Tuple.C y) =>
    (y, y) -> T (Graph2D.T x y) -> T (Graph2D.T x y)
-yRange2d = range Option.yRange
+yRange2d = range Option.yRangeBounds
 
 
 xRange3d ::
    (Atom.C x, Atom.C y, Atom.C z, Tuple.C x) =>
    (x, x) -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
-xRange3d = range Option.xRange
+xRange3d = range Option.xRangeBounds
 
 yRange3d ::
    (Atom.C x, Atom.C y, Atom.C z, Tuple.C y) =>
    (y, y) -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
-yRange3d = range Option.yRange
+yRange3d = range Option.yRangeBounds
 
 zRange3d ::
    (Atom.C x, Atom.C y, Atom.C z, Tuple.C z) =>
    (z, z) -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
-zRange3d = range Option.zRange
+zRange3d = range Option.zRangeBounds
 
 
 range ::
@@ -110,15 +122,15 @@
 
 
 xLabel :: Graph.C graph => String -> T graph -> T graph
-xLabel = label Option.xLabel
+xLabel = label Option.xLabelText
 
 yLabel :: Graph.C graph => String -> T graph -> T graph
-yLabel = label Option.yLabel
+yLabel = label Option.yLabelText
 
 zLabel ::
    (Atom.C x, Atom.C y, Atom.C z) =>
    String -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
-zLabel = label Option.zLabel
+zLabel = label Option.zLabelText
 
 label :: Graph.C graph => Option.T -> String -> T graph -> T graph
 label opt x =
@@ -161,20 +173,60 @@
 viewMap =
    OptionSet.add Option.view ["map"]
 
-{-
-xTicks :: Graph.C graph => Double -> Double -> T graph -> T graph
-xTicks = ticks Option.xTicks
 
-yTicks :: Graph.C graph => Double -> Double -> T graph -> T graph
-yTicks = ticks Option.yTicks
+xTicks2d ::
+   (Atom.C x, Atom.C y, Tuple.C x) =>
+   [(String, x)] -> T (Graph2D.T x y) -> T (Graph2D.T x y)
+xTicks2d = ticks Option.xTickLabels
 
-zTicks :: Double -> Double -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
-zTicks = ticks Option.zTicks
+yTicks2d ::
+   (Atom.C x, Atom.C y, Tuple.C y) =>
+   [(String, y)] -> T (Graph2D.T x y) -> T (Graph2D.T x y)
+yTicks2d = ticks Option.yTickLabels
 
-ticks :: Graph.C graph => Option.T -> Double -> Double -> T graph -> T graph
-ticks opt x y =
-   OptionSet.add opt [show x ++ ":" ++ show y]
--}
+
+xTicks3d ::
+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C x) =>
+   [(String, x)] -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
+xTicks3d = ticks Option.xTickLabels
+
+yTicks3d ::
+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C y) =>
+   [(String, y)] -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
+yTicks3d = ticks Option.yTickLabels
+
+zTicks3d ::
+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C z) =>
+   [(String, z)] -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
+zTicks3d = ticks Option.zTickLabels
+
+
+ticks ::
+   (Atom.C a, Tuple.C a, Graph.C graph) =>
+   Option.T -> [(String, a)] -> T graph -> T graph
+ticks opt labels =
+   OptionSet.add opt
+      [('(' :) $ foldr ($) ")" $
+       List.intersperse (showString ", ") $
+       map
+          (\(lab,pos) ->
+             showString (quote lab) .
+             showString " " .
+             atomText pos)
+          labels]
+
+
+boxwidthRelative ::
+   (Graph.C graph) =>
+   Double -> T graph -> T graph
+boxwidthRelative width =
+   OptionSet.add Option.boxwidth [show width, "relative"]
+
+boxwidthAbsolute ::
+   (Graph.C graph) =>
+   Double -> T graph -> T graph
+boxwidthAbsolute width =
+   OptionSet.add Option.boxwidth [show width, "absolute"]
 
 {-
 cornerToColor :: CornersToColor -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)
diff --git a/src/Graphics/Gnuplot/Frame/OptionSet/Histogram.hs b/src/Graphics/Gnuplot/Frame/OptionSet/Histogram.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Gnuplot/Frame/OptionSet/Histogram.hs
@@ -0,0 +1,61 @@
+module Graphics.Gnuplot.Frame.OptionSet.Histogram (
+   clustered,
+   clusteredGap,
+   errorbars,
+   errorbarsGap,
+   errorbarsGapLineWidth,
+   rowstacked,
+   columnstacked,
+   ) where
+
+import qualified Graphics.Gnuplot.Graph.TwoDimensional as Graph2D
+
+import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet
+import qualified Graphics.Gnuplot.Private.FrameOption as Option
+
+import qualified Graphics.Gnuplot.Value.Atom as Atom
+
+import Graphics.Gnuplot.Private.FrameOptionSet (T, )
+
+
+clustered ::
+   (Atom.C x, Atom.C y) =>
+   T (Graph2D.T x y) -> T (Graph2D.T x y)
+clustered =
+   OptionSet.add Option.styleHistogram ["clustered"]
+
+clusteredGap ::
+   (Atom.C x, Atom.C y) =>
+   Double -> T (Graph2D.T x y) -> T (Graph2D.T x y)
+clusteredGap gapSize =
+   OptionSet.add Option.styleHistogram ["clustered", "gap", show gapSize]
+
+errorbars ::
+   (Atom.C x, Atom.C y) =>
+   T (Graph2D.T x y) -> T (Graph2D.T x y)
+errorbars =
+   OptionSet.add Option.styleHistogram ["errorbars"]
+
+errorbarsGap ::
+   (Atom.C x, Atom.C y) =>
+   Double -> T (Graph2D.T x y) -> T (Graph2D.T x y)
+errorbarsGap gapSize =
+   OptionSet.add Option.styleHistogram ["errorbars", "gap", show gapSize]
+
+errorbarsGapLineWidth ::
+   (Atom.C x, Atom.C y) =>
+   Double -> Double -> T (Graph2D.T x y) -> T (Graph2D.T x y)
+errorbarsGapLineWidth gapSize width =
+   OptionSet.add Option.styleHistogram ["errorbars", "gap", show gapSize, show width]
+
+rowstacked ::
+   (Atom.C x, Atom.C y) =>
+   T (Graph2D.T x y) -> T (Graph2D.T x y)
+rowstacked =
+   OptionSet.add Option.styleHistogram ["rowstacked"]
+
+columnstacked ::
+   (Atom.C x, Atom.C y) =>
+   T (Graph2D.T x y) -> T (Graph2D.T x y)
+columnstacked =
+   OptionSet.add Option.styleHistogram ["columnstacked"]
diff --git a/src/Graphics/Gnuplot/Frame/OptionSet/Style.hs b/src/Graphics/Gnuplot/Frame/OptionSet/Style.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Gnuplot/Frame/OptionSet/Style.hs
@@ -0,0 +1,28 @@
+module Graphics.Gnuplot.Frame.OptionSet.Style (
+   fillSolid,
+   fillBorder,
+   fillBorderLineType,
+   ) where
+
+import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet
+import qualified Graphics.Gnuplot.Private.FrameOption as Option
+import qualified Graphics.Gnuplot.Private.Graph as Graph
+
+import Graphics.Gnuplot.Private.FrameOptionSet (T, )
+
+-- import Graphics.Gnuplot.Utility (quote, )
+
+
+fillSolid :: Graph.C graph => T graph -> T graph
+fillSolid =
+   OptionSet.add Option.styleFillSolid ["solid"]
+
+fillBorder :: Graph.C graph => Bool -> T graph -> T graph
+fillBorder on =
+   if on
+     then OptionSet.add Option.styleFillBorder ["border"]
+     else OptionSet.add Option.styleFillBorder ["noborder"]
+
+fillBorderLineType :: Graph.C graph => Int -> T graph -> T graph
+fillBorderLineType n =
+   OptionSet.add Option.styleFillBorder ["border", show n]
diff --git a/src/Graphics/Gnuplot/Graph/TwoDimensional.hs b/src/Graphics/Gnuplot/Graph/TwoDimensional.hs
--- a/src/Graphics/Gnuplot/Graph/TwoDimensional.hs
+++ b/src/Graphics/Gnuplot/Graph/TwoDimensional.hs
@@ -11,6 +11,7 @@
    listLinesPoints,
    listImpulses,
    listDots,
+   histograms,
 
    xErrorBarsRelative,
    yErrorBarsRelative,
diff --git a/src/Graphics/Gnuplot/MultiPlot.hs b/src/Graphics/Gnuplot/MultiPlot.hs
--- a/src/Graphics/Gnuplot/MultiPlot.hs
+++ b/src/Graphics/Gnuplot/MultiPlot.hs
@@ -5,12 +5,13 @@
    partFromPlot,
    simpleFromFrameArray,
    simpleFromPartArray,
+   title,
    ) where
 
 import qualified Graphics.Gnuplot.Private.Frame as Frame
 import qualified Graphics.Gnuplot.Private.Plot as Plot
 
-import qualified Graphics.Gnuplot.Display as Display
+import qualified Graphics.Gnuplot.Private.Display as Display
 import qualified Graphics.Gnuplot.Private.Graph as Graph
 
 import qualified Data.Monoid.State as State
@@ -19,10 +20,12 @@
 import Data.Array (Array, elems, bounds, )
 import Data.Ix (Ix, rangeSize, )
 
+import Graphics.Gnuplot.Utility (quote, )
 
+
 data T =
    Cons {
-      _option :: (),  -- to be extended by multiplot options
+      title_ :: Maybe String,
       numRows, numColumns :: Int,
       parts :: [Part]
    }
@@ -60,19 +63,25 @@
    Array (i,j) Part -> T
 simpleFromPartArray arr =
    let ((r0,c0), (r1,c1)) = bounds arr
-   in  Cons ()
+   in  Cons Nothing
           (rangeSize (r0,r1))
           (rangeSize (c0,c1))
           (elems arr)
 
 
+title :: String -> T -> T
+title str mp =
+   mp {title_ = Just str}
+
+
 instance Display.C T where
    toScript mp =
       mconcat $
       (Display.Script $ State.pure $
-         Display.Body [] ["set multiplot layout " ++
-                      show (numRows mp) ++ ", " ++
-                      show (numColumns mp)]) :
+         Display.Body []
+            ["set multiplot layout " ++
+             show (numRows mp) ++ ", " ++ show (numColumns mp) ++
+             maybe "" ((" title " ++) . quote) (title_ mp)]) :
       (map scriptFromPart $ parts mp) ++
       (Display.Script $ State.pure $
          Display.Body [] ["unset multiplot"]) :
diff --git a/src/Graphics/Gnuplot/Plot/ThreeDimensional.hs b/src/Graphics/Gnuplot/Plot/ThreeDimensional.hs
--- a/src/Graphics/Gnuplot/Plot/ThreeDimensional.hs
+++ b/src/Graphics/Gnuplot/Plot/ThreeDimensional.hs
@@ -37,7 +37,8 @@
 cloud typ ps =
    Plot.withUniqueFile
       (assembleCells (map Tuple.text ps))
-      [Graph.deflt typ [1 .. Type.tupleSize typ]]
+      [Graph.deflt typ
+         [1 .. case Type.tupleSize typ of Tuple.ColumnCount n -> n]]
 
 {-
 function ::
diff --git a/src/Graphics/Gnuplot/Plot/TwoDimensional.hs b/src/Graphics/Gnuplot/Plot/TwoDimensional.hs
--- a/src/Graphics/Gnuplot/Plot/TwoDimensional.hs
+++ b/src/Graphics/Gnuplot/Plot/TwoDimensional.hs
@@ -47,7 +47,8 @@
 list typ ps =
    Plot.withUniqueFile
       (assembleCells (map Tuple.text ps))
-      [Graph.deflt typ [1 .. Type.tupleSize typ]]
+      [Graph.deflt typ
+         [1 .. case Type.tupleSize typ of Tuple.ColumnCount n -> n]]
 
 {- |
 > function Type.line (linearScale 1000 (-10,10)) sin
@@ -72,13 +73,14 @@
        typA = undefined
        typB :: Type.T x y (a,b) -> Type.T x y b
        typB = undefined
-       na = Type.tupleSize (typA typ)
+       Tuple.ColumnCount na = Type.tupleSize (typA typ)
+       Tuple.ColumnCount nb = Type.tupleSize (typB typ)
    in  Plot.withUniqueFile
           (assembleCells
-             (map (\(a,b) -> Tuple.text a ++ concatMap Tuple.text b) dat))
+              (map (\(a,b) -> Tuple.text a ++ concatMap Tuple.text b) dat))
           (Match.take fs $
            map (\ns -> Graph.deflt typ ([1..na] ++ ns)) $
-           ListHT.sliceVertical (Type.tupleSize (typB typ)) [(na+1)..])
+           ListHT.sliceVertical nb [(na+1)..])
 
 
 {- |
diff --git a/src/Graphics/Gnuplot/Private/Display.hs b/src/Graphics/Gnuplot/Private/Display.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Gnuplot/Private/Display.hs
@@ -0,0 +1,53 @@
+module Graphics.Gnuplot.Private.Display where
+
+import qualified Graphics.Gnuplot.Private.FrameOption as Option
+
+import qualified Data.Map as Map
+import qualified Data.Monoid.State as State
+import Data.Monoid (Monoid, mempty, mappend, )
+
+
+newtype Script =
+   Script {
+      runScript :: State.T (Int, OptionSet) Body
+   }
+
+data Body =
+   Body {
+      files :: [File],
+      commands :: [String]
+   }
+
+type OptionSet = Map.Map Option.T [String]
+
+data File =
+   File {
+      filename :: FilePath,
+      content :: String
+   }
+
+writeData :: File -> IO ()
+writeData (File fn cont) =
+   writeFile fn cont
+
+
+{-
+Could also be implemented with Control.Monad.Trans.State:
+mappend = liftA2 mappend
+-}
+instance Monoid Script where
+   mempty = Script mempty
+   mappend (Script b0) (Script b1) =
+      Script (mappend b0 b1)
+
+{-
+Could also be implemented with Control.Monad.Trans.State:
+mappend = liftA2 mappend
+-}
+instance Monoid Body where
+   mempty = Body mempty mempty
+   mappend (Body f0 c0) (Body f1 c1) =
+      Body (mappend f0 f1) (mappend c0 c1)
+
+class C gfx where
+   toScript :: gfx -> Script
diff --git a/src/Graphics/Gnuplot/Private/Frame.hs b/src/Graphics/Gnuplot/Private/Frame.hs
--- a/src/Graphics/Gnuplot/Private/Frame.hs
+++ b/src/Graphics/Gnuplot/Private/Frame.hs
@@ -3,7 +3,7 @@
 import qualified Graphics.Gnuplot.Private.Plot as Plot
 import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet
 
-import qualified Graphics.Gnuplot.Display as Display
+import qualified Graphics.Gnuplot.Private.Display as Display
 import qualified Graphics.Gnuplot.Private.Graph as Graph
 
 import qualified Data.Monoid.State as State
diff --git a/src/Graphics/Gnuplot/Private/FrameOption.hs b/src/Graphics/Gnuplot/Private/FrameOption.hs
--- a/src/Graphics/Gnuplot/Private/FrameOption.hs
+++ b/src/Graphics/Gnuplot/Private/FrameOption.hs
@@ -1,37 +1,76 @@
+{- |
+If you add a new option,
+please mind to add a default value to FrameOptionSet.deflt, too.
+-}
 module Graphics.Gnuplot.Private.FrameOption where
 
-newtype T = Cons String
+{- |
+Every option represents an internal state in gnuplot.
+It is altered with gnuplot's set command.
+The first field in 'T' is the name of the option
+and the name of the according internal state in gnuplot.
+Sometimes the addressed state is not explicitly mentioned
+but is expressed by the syntax of the values.
+For this case we manage an identifier in the second field.
+It is only used for distinguishing between these states,
+but it is never written to a gnuplot script.
+-}
+data T = Cons String String
    deriving (Eq, Ord, Show)
 
-custom :: String -> T
+custom :: String -> String -> T
 custom = Cons
 
-title  :: T; title  = Cons "title"
-grid   :: T; grid   = Cons "grid"
-size   :: T; size   = Cons "size"
-key    :: T; key    = Cons "key"
-border :: T; border = Cons "border"
-pm3d   :: T; pm3d   = Cons "pm3d"
-view   :: T; view   = Cons "view"
+grid   :: String -> T; grid   = Cons "grid"
+size   :: String -> T; size   = Cons "size"
+key    :: String -> T; key    = Cons "key"
+border :: String -> T; border = Cons "border"
+pm3d   :: String -> T; pm3d   = Cons "pm3d"
 
-xRange :: T; xRange = Cons "xrange"
-yRange :: T; yRange = Cons "yrange"
-zRange :: T; zRange = Cons "zrange"
+xRange :: String -> T; xRange = Cons "xrange"
+yRange :: String -> T; yRange = Cons "yrange"
+zRange :: String -> T; zRange = Cons "zrange"
 
-xLabel :: T; xLabel = Cons "xlabel"
-yLabel :: T; yLabel = Cons "ylabel"
-zLabel :: T; zLabel = Cons "zlabel"
+xLabel :: String -> T; xLabel = Cons "xlabel"
+yLabel :: String -> T; yLabel = Cons "ylabel"
+zLabel :: String -> T; zLabel = Cons "zlabel"
 
-xTicks :: T; xTicks = Cons "xtics"
-yTicks :: T; yTicks = Cons "ytics"
-zTicks :: T; zTicks = Cons "ztics"
+xTicks :: String -> T; xTicks = Cons "xtics"
+yTicks :: String -> T; yTicks = Cons "ytics"
+zTicks :: String -> T; zTicks = Cons "ztics"
 
-xData  :: T; xData  = Cons "xdata"
-yData  :: T; yData  = Cons "ydata"
-zData  :: T; zData  = Cons "zdata"
 
-xFormat :: T; xFormat = Cons "format x"
-yFormat :: T; yFormat = Cons "format y"
-zFormat :: T; zFormat = Cons "format z"
+title :: T; title = Cons "title" ""
+view  :: T; view  = Cons "view" ""
 
-timeFmt :: T; timeFmt = Cons "timefmt"
+xFormat :: T; xFormat = Cons "format x" ""
+yFormat :: T; yFormat = Cons "format y" ""
+zFormat :: T; zFormat = Cons "format z" ""
+
+timeFmt :: T; timeFmt = Cons "timefmt" ""
+
+xData :: T; xData = Cons "xdata" ""
+yData :: T; yData = Cons "ydata" ""
+zData :: T; zData = Cons "zdata" ""
+
+
+sizeScale :: T; sizeScale = size "scale"
+keyShow   :: T; keyShow   = key "show"
+
+xRangeBounds :: T; xRangeBounds = xRange "bounds"
+yRangeBounds :: T; yRangeBounds = yRange "bounds"
+zRangeBounds :: T; zRangeBounds = zRange "bounds"
+
+xLabelText :: T; xLabelText = xLabel "text"
+yLabelText :: T; yLabelText = yLabel "text"
+zLabelText :: T; zLabelText = zLabel "text"
+
+xTickLabels :: T; xTickLabels = xTicks "labels"
+yTickLabels :: T; yTickLabels = yTicks "labels"
+zTickLabels :: T; zTickLabels = zTicks "labels"
+
+boxwidth :: T; boxwidth = Cons "boxwidth" ""
+
+styleFillSolid  :: T; styleFillSolid  = Cons "style fill" "solid"
+styleFillBorder :: T; styleFillBorder = Cons "style fill" "border"
+styleHistogram  :: T; styleHistogram  = Cons "style histogram" ""
diff --git a/src/Graphics/Gnuplot/Private/FrameOptionSet.hs b/src/Graphics/Gnuplot/Private/FrameOptionSet.hs
--- a/src/Graphics/Gnuplot/Private/FrameOptionSet.hs
+++ b/src/Graphics/Gnuplot/Private/FrameOptionSet.hs
@@ -32,21 +32,25 @@
 deflt :: Plain
 deflt =
    Map.fromList $
-   (Option.key, []) :
-   (Option.border, []) :
-   (Option.xLabel, []) :
-   (Option.yLabel, []) :
-   (Option.zLabel, []) :
-   (Option.xRange, ["[*:*]"]) :
-   (Option.yRange, ["[*:*]"]) :
-   (Option.zRange, ["[*:*]"]) :
-   (Option.xTicks, []) :
-   (Option.yTicks, []) :
-   (Option.zTicks, []) :
+   (Option.keyShow, []) :
+--   (Option.border, []) :
+   (Option.xLabelText, []) :
+   (Option.yLabelText, []) :
+   (Option.zLabelText, []) :
+   (Option.xRangeBounds, ["[*:*]"]) :
+   (Option.yRangeBounds, ["[*:*]"]) :
+   (Option.zRangeBounds, ["[*:*]"]) :
    (Option.xFormat, []) :
    (Option.yFormat, []) :
    (Option.zFormat, []) :
+   (Option.xTickLabels, []) :
+   (Option.yTickLabels, []) :
+   (Option.zTickLabels, []) :
+   (Option.styleFillSolid, ["0"]) :
+   (Option.styleFillBorder, []) :
+   (Option.styleHistogram, ["clustered"]) :
 --   (Option.timeFmt, [quote "%s"]) :
+   (Option.boxwidth, []) :
    []
 
 initial :: Plain
@@ -83,7 +87,7 @@
 diffToString :: Plain -> Plain -> [String]
 diffToString m0 m1 =
    mapMaybe
-      (\(Option.Cons opt, (old,new)) ->
+      (\(Option.Cons opt _, (old,new)) ->
          toMaybe (old/=new) $
          maybe
             ("unset " ++ opt)
@@ -94,3 +98,9 @@
       (\(old,_) (_,new) -> (old,new))
       (fmap (\x -> (Just x, Nothing)) m0)
       (fmap (\x -> (Nothing, Just x)) m1)
+
+boolean :: Option.T -> Bool -> T graph -> T graph
+boolean opt on =
+   if on
+     then add opt []
+     else remove opt
diff --git a/src/Graphics/Gnuplot/Private/Graph2D.hs b/src/Graphics/Gnuplot/Private/Graph2D.hs
--- a/src/Graphics/Gnuplot/Private/Graph2D.hs
+++ b/src/Graphics/Gnuplot/Private/Graph2D.hs
@@ -14,17 +14,17 @@
 
 data T x y =
    Cons {
-      column_   :: Column,
+      column_   :: Columns,
       type_     :: Type,
       lineSpec_ :: LineSpec.T
    }
 
-type Column = [Int]
+type Columns = [Int]
 
 type Type = String
 
 
-columnToString :: Column -> String
+columnToString :: Columns -> String
 columnToString =
    concat . List.intersperse ":" . map show
 
@@ -36,31 +36,31 @@
 
 
 type AxisOption x y a =
-   OptionSet.T (T x y) -> (Atom.OptionSet, a)
+   OptionSet.T (T x y) -> Atom.OptionSet a
 
 defltOptions :: (Atom.C x, Atom.C y) => OptionSet.T (T x y)
 defltOptions =
-   let optX :: Atom.C x => AxisOption x y x
-       optX _ = Atom.options
-       optY :: Atom.C y => AxisOption x y y
-       optY _ = Atom.options
-       mk :: Option.T -> Option.T ->
-             (Atom.OptionSet, a) -> [(Option.T, [String])]
-       mk optData optFormat op =
-          let opts = fst op
-          in  (optData, Atom.optData opts) :
-              (optFormat, Atom.optFormat opts) :
-              Atom.optOthers opts
-       result =
+   let mk ::
+          Option.T -> Option.T ->
+          Atom.OptionSet a -> [(Option.T, [String])]
+       mk optData optFormat opts =
+          (optData, Atom.optData opts) :
+          (optFormat, Atom.optFormat opts) :
+          Atom.optOthers opts
+       result ::
+          Atom.OptionSet x ->
+          Atom.OptionSet y ->
+          OptionSet.T (T x y)
+       result optX optY =
           OptionSet.Cons $
           flip Map.union OptionSet.deflt $
           Map.fromList $
-          mk Option.xData Option.xFormat (optX result) ++
-          mk Option.yData Option.yFormat (optY result) ++
+          mk Option.xData Option.xFormat optX ++
+          mk Option.yData Option.yFormat optY ++
           (Option.zData, []) :
           (Option.zFormat, []) :
           []
-   in  result
+   in  result Atom.options Atom.options
 
 
 instance (Atom.C x, Atom.C y) => Graph.C (T x y) where
@@ -69,7 +69,7 @@
    defltOptions = defltOptions
 
 
-deflt :: GraphType.T x y a -> Column -> T x y
+deflt :: GraphType.T x y a -> Columns -> T x y
 deflt t c = Cons c (GraphType.toString t) LineSpec.deflt
 
 typ :: Type -> T x y -> T x y
diff --git a/src/Graphics/Gnuplot/Private/Graph2DType.hs b/src/Graphics/Gnuplot/Private/Graph2DType.hs
--- a/src/Graphics/Gnuplot/Private/Graph2DType.hs
+++ b/src/Graphics/Gnuplot/Private/Graph2DType.hs
@@ -5,13 +5,17 @@
 import Prelude hiding (lines, )
 
 
+{- |
+The type parameter @x@ is for the values on the X axis,
+@y@ of the Y axis and
+@a@ is the type of the plotted data.
+The type @a@ is a pair in case of points in the plane,
+or a more complex tuple in case of error plots and the like.
+-}
 newtype T x y a = Cons String
 
-tupleSize :: (Tuple.C a) => T x y a -> Int
-tupleSize =
-   let size :: (Tuple.C a) => T x y a -> (Int, a)
-       size _ = Tuple.number
-   in  fst . size
+tupleSize :: (Tuple.C a) => T x y a -> Tuple.ColumnCount a
+tupleSize _ = Tuple.columnCount
 
 
 {-
@@ -23,6 +27,7 @@
 listLinesPoints :: (Atom.C y) => T Int y y
 listImpulses    :: (Atom.C y) => T Int y y
 listDots        :: (Atom.C y) => T Int y y
+histograms      :: (Atom.C y) => T Int y y
 
 xErrorBarsRelative   :: (Atom.C x, Atom.C y) => T x y ((x,y),x)
 yErrorBarsRelative   :: (Atom.C x, Atom.C y) => T x y ((x,y),y)
@@ -64,6 +69,7 @@
 listLinesPoints = Cons "linespoints"
 listImpulses    = Cons "impulses"
 listDots        = Cons "dots"
+histograms      = Cons "histograms"
 
 xErrorBarsRelative   = Cons "xerrorbars"
 yErrorBarsRelative   = Cons "yerrorbars"
diff --git a/src/Graphics/Gnuplot/Private/Graph3D.hs b/src/Graphics/Gnuplot/Private/Graph3D.hs
--- a/src/Graphics/Gnuplot/Private/Graph3D.hs
+++ b/src/Graphics/Gnuplot/Private/Graph3D.hs
@@ -8,14 +8,14 @@
 import qualified Graphics.Gnuplot.Value.Atom as Atom
 import qualified Data.Map as Map
 
-import Graphics.Gnuplot.Private.Graph2D (Column, columnToString, )
+import Graphics.Gnuplot.Private.Graph2D (Columns, columnToString, )
 
 import Prelude hiding (lines, )
 
 
 data T x y z =
    Cons {
-      column_   :: Column,
+      column_   :: Columns,
       type_     :: Type,
       lineSpec_ :: LineSpec.T
    }
@@ -31,32 +31,32 @@
 
 
 type AxisOption x y z a =
-   OptionSet.T (T x y z) -> (Atom.OptionSet, a)
+   OptionSet.T (T x y z) -> Atom.OptionSet a
 
 defltOptions :: (Atom.C x, Atom.C y, Atom.C z) => OptionSet.T (T x y z)
 defltOptions =
-   let optX :: Atom.C x => AxisOption x y z x
-       optX _ = Atom.options
-       optY :: Atom.C y => AxisOption x y z y
-       optY _ = Atom.options
-       optZ :: Atom.C z => AxisOption x y z z
-       optZ _ = Atom.options
-       mk :: Option.T -> Option.T ->
-             (Atom.OptionSet, a) -> [(Option.T, [String])]
-       mk optData optFormat op =
-          let opts = fst op
-          in  (optData, Atom.optData opts) :
-              (optFormat, Atom.optFormat opts) :
-              Atom.optOthers opts
-       result =
+   let mk ::
+          Option.T -> Option.T ->
+          Atom.OptionSet a ->
+          [(Option.T, [String])]
+       mk optData optFormat opts =
+          (optData, Atom.optData opts) :
+          (optFormat, Atom.optFormat opts) :
+          Atom.optOthers opts
+       result ::
+          Atom.OptionSet x ->
+          Atom.OptionSet y ->
+          Atom.OptionSet z ->
+          OptionSet.T (T x y z)
+       result optX optY optZ =
           OptionSet.Cons $
           flip Map.union OptionSet.deflt $
           Map.fromList $
-          mk Option.xData Option.xFormat (optX result) ++
-          mk Option.yData Option.yFormat (optY result) ++
-          mk Option.yData Option.yFormat (optZ result) ++
+          mk Option.xData Option.xFormat optX ++
+          mk Option.yData Option.yFormat optY ++
+          mk Option.yData Option.yFormat optZ ++
           []
-   in  result
+   in  result Atom.options Atom.options Atom.options
 
 
 instance (Atom.C x, Atom.C y, Atom.C z) => Graph.C (T x y z) where
@@ -65,7 +65,7 @@
    defltOptions = defltOptions
 
 
-deflt :: GraphType.T x y z a -> Column -> T x y z
+deflt :: GraphType.T x y z a -> Columns -> T x y z
 deflt t c = Cons c (GraphType.toString t) LineSpec.deflt
 
 typ :: Type -> T x y z -> T x y z
diff --git a/src/Graphics/Gnuplot/Private/Graph3DType.hs b/src/Graphics/Gnuplot/Private/Graph3DType.hs
--- a/src/Graphics/Gnuplot/Private/Graph3DType.hs
+++ b/src/Graphics/Gnuplot/Private/Graph3DType.hs
@@ -8,11 +8,8 @@
 
 newtype T x y z a = Cons String
 
-tupleSize :: (Tuple.C a) => T x y z a -> Int
-tupleSize =
-   let size :: (Tuple.C a) => T x y z a -> (Int, a)
-       size _ = Tuple.number
-   in  fst . size
+tupleSize :: (Tuple.C a) => T x y z a -> Tuple.ColumnCount a
+tupleSize _ = Tuple.columnCount
 
 
 {-
diff --git a/src/Graphics/Gnuplot/Private/Plot.hs b/src/Graphics/Gnuplot/Private/Plot.hs
--- a/src/Graphics/Gnuplot/Private/Plot.hs
+++ b/src/Graphics/Gnuplot/Private/Plot.hs
@@ -3,7 +3,7 @@
 import qualified Data.Monoid.State as State
 import Data.Monoid (Monoid, mempty, mappend, )
 
-import qualified Graphics.Gnuplot.Display as Display
+import qualified Graphics.Gnuplot.Private.Display as Display
 import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet
 import qualified Graphics.Gnuplot.Private.Graph as Graph
 import Graphics.Gnuplot.Utility (quote, commaConcat, )
diff --git a/src/Graphics/Gnuplot/Private/Terminal.hs b/src/Graphics/Gnuplot/Private/Terminal.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Gnuplot/Private/Terminal.hs
@@ -0,0 +1,18 @@
+module Graphics.Gnuplot.Private.Terminal where
+
+data T =
+   Cons {
+      options :: [String],
+      commands :: [String]
+   }
+
+class C terminal where
+   canonical :: terminal -> T
+
+deflt :: T
+deflt = Cons ["x11"] []
+
+
+formatBool :: String -> Bool -> String
+formatBool name b =
+   if b then name else "no"++name
diff --git a/src/Graphics/Gnuplot/Simple.hs b/src/Graphics/Gnuplot/Simple.hs
--- a/src/Graphics/Gnuplot/Simple.hs
+++ b/src/Graphics/Gnuplot/Simple.hs
@@ -64,7 +64,7 @@
 import qualified Graphics.Gnuplot.Terminal.SVG as SVG
 -}
 
-import qualified Graphics.Gnuplot.Terminal as Terminal
+import qualified Graphics.Gnuplot.Private.Terminal as Terminal
 import qualified Graphics.Gnuplot.Execute as Exec
 
 import System.Cmd (rawSystem, )
diff --git a/src/Graphics/Gnuplot/Terminal.hs b/src/Graphics/Gnuplot/Terminal.hs
--- a/src/Graphics/Gnuplot/Terminal.hs
+++ b/src/Graphics/Gnuplot/Terminal.hs
@@ -1,18 +1,3 @@
-module Graphics.Gnuplot.Terminal where
-
-data T =
-   Cons {
-      options :: [String],
-      commands :: [String]
-   }
-
-class C terminal where
-   canonical :: terminal -> T
-
-deflt :: T
-deflt = Cons ["x11"] []
-
+module Graphics.Gnuplot.Terminal (C, ) where
 
-formatBool :: String -> Bool -> String
-formatBool name b =
-   if b then name else "no"++name
+import Graphics.Gnuplot.Private.Terminal
diff --git a/src/Graphics/Gnuplot/Terminal/PNG.hs b/src/Graphics/Gnuplot/Terminal/PNG.hs
--- a/src/Graphics/Gnuplot/Terminal/PNG.hs
+++ b/src/Graphics/Gnuplot/Terminal/PNG.hs
@@ -6,8 +6,8 @@
    fontTiny, fontSmall, fontMedium, fontLarge, fontGiant,
    ) where
 
-import qualified Graphics.Gnuplot.Terminal as Terminal
-import Graphics.Gnuplot.Terminal (formatBool, )
+import qualified Graphics.Gnuplot.Private.Terminal as Terminal
+import Graphics.Gnuplot.Private.Terminal (formatBool, )
 import Data.Maybe (catMaybes, )
 import Graphics.Gnuplot.Utility (quote, )
 
diff --git a/src/Graphics/Gnuplot/Terminal/PostScript.hs b/src/Graphics/Gnuplot/Terminal/PostScript.hs
--- a/src/Graphics/Gnuplot/Terminal/PostScript.hs
+++ b/src/Graphics/Gnuplot/Terminal/PostScript.hs
@@ -5,7 +5,7 @@
    font, embedFont,
    ) where
 
-import qualified Graphics.Gnuplot.Terminal as Terminal
+import qualified Graphics.Gnuplot.Private.Terminal as Terminal
 import Graphics.Gnuplot.Utility (quote, )
 import Data.Maybe (maybeToList, )
 
diff --git a/src/Graphics/Gnuplot/Terminal/SVG.hs b/src/Graphics/Gnuplot/Terminal/SVG.hs
--- a/src/Graphics/Gnuplot/Terminal/SVG.hs
+++ b/src/Graphics/Gnuplot/Terminal/SVG.hs
@@ -2,7 +2,7 @@
    T, cons,
    ) where
 
-import qualified Graphics.Gnuplot.Terminal as Terminal
+import qualified Graphics.Gnuplot.Private.Terminal as Terminal
 import Graphics.Gnuplot.Utility (quote, )
 
 
diff --git a/src/Graphics/Gnuplot/Terminal/WXT.hs b/src/Graphics/Gnuplot/Terminal/WXT.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Gnuplot/Terminal/WXT.hs
@@ -0,0 +1,53 @@
+{- |
+Terminal using wxwidgets.
+Derived from X11.
+-}
+module Graphics.Gnuplot.Terminal.WXT (
+   T, cons,
+   title, noTitle,
+   persist, noPersist,
+   ) where
+
+import qualified Graphics.Gnuplot.Private.Terminal as Terminal
+import Graphics.Gnuplot.Private.Terminal (formatBool, )
+import Data.Maybe (catMaybes, )
+import Graphics.Gnuplot.Utility (quote, )
+
+
+data T =
+   Cons {
+      title_ :: Maybe String,
+      persist_ :: Maybe Bool
+   }
+
+cons :: T
+cons =
+   Cons {
+      title_ = Nothing,
+      persist_ = Nothing
+   }
+
+
+title :: String -> T -> T
+title text term = term{title_ = Just text}
+
+noTitle :: T -> T
+noTitle term = term{title_ = Nothing}
+
+persist, noPersist :: T -> T
+persist   term = term{persist_ = Just True}
+noPersist term = term{persist_ = Just False}
+
+
+instance Terminal.C T where
+   canonical term =
+      Terminal.Cons {
+         Terminal.options =
+            "wxt" :
+            catMaybes (
+               (fmap quote $ title_ term) :
+               (fmap (formatBool "persist") $ persist_ term) :
+               []),
+         Terminal.commands =
+            []
+      }
diff --git a/src/Graphics/Gnuplot/Terminal/X11.hs b/src/Graphics/Gnuplot/Terminal/X11.hs
--- a/src/Graphics/Gnuplot/Terminal/X11.hs
+++ b/src/Graphics/Gnuplot/Terminal/X11.hs
@@ -4,8 +4,8 @@
    persist, noPersist,
    ) where
 
-import qualified Graphics.Gnuplot.Terminal as Terminal
-import Graphics.Gnuplot.Terminal (formatBool, )
+import qualified Graphics.Gnuplot.Private.Terminal as Terminal
+import Graphics.Gnuplot.Private.Terminal (formatBool, )
 import Data.Maybe (catMaybes, )
 import Graphics.Gnuplot.Utility (quote, )
 
diff --git a/src/Graphics/Gnuplot/Value/Atom.hs b/src/Graphics/Gnuplot/Value/Atom.hs
--- a/src/Graphics/Gnuplot/Value/Atom.hs
+++ b/src/Graphics/Gnuplot/Value/Atom.hs
@@ -2,7 +2,10 @@
 Provide a class that restricts the range of Haskell types
 to the ones that gnuplot can process.
 -}
-module Graphics.Gnuplot.Value.Atom where
+module Graphics.Gnuplot.Value.Atom (
+   OptionSet(..),
+   C(..),
+   ) where
 
 import qualified Graphics.Gnuplot.Private.FrameOption as Option
 import Graphics.Gnuplot.Utility (quote, )
@@ -13,7 +16,7 @@
 import Data.Ratio (Ratio, )
 
 
-data OptionSet =
+data OptionSet a =
    OptionSet {
       optData :: [String],
       optFormat :: [String],
@@ -21,10 +24,9 @@
    }
 
 class C a where
-   options :: (OptionSet, a)
+   options :: OptionSet a
    options =
-      (OptionSet [] [{- quote "%g" -}] [],
-       error "gnuplot: dummy atomic value")
+      OptionSet [] [{- quote "%g" -}] []
 
 instance C Float   where
 instance C Double  where
@@ -42,13 +44,11 @@
 instance C Word64 where
 
 
-timeOptions :: OptionSet
+timeOptions :: OptionSet time
 timeOptions =
    OptionSet ["time"] [quote "%d/%m"] [(Option.timeFmt, [quote "%s"])]
 
 instance C Time.Day where
-   options =
-      (timeOptions, error "gnuplot: dummy day value")
+   options = timeOptions
 instance C Time.UTCTime where
-   options =
-      (timeOptions, error "gnuplot: dummy utctime value")
+   options = timeOptions
diff --git a/src/Graphics/Gnuplot/Value/ColumnSet.hs b/src/Graphics/Gnuplot/Value/ColumnSet.hs
--- a/src/Graphics/Gnuplot/Value/ColumnSet.hs
+++ b/src/Graphics/Gnuplot/Value/ColumnSet.hs
@@ -11,6 +11,19 @@
 
 newtype T a = Cons [Int]
 
+{-
+Functor and Applicative instances would be useful
+for combining column sets,
+but they are dangerous, because they can bring
+type and column number out of sync.
+
+instance Functor Column where
+   fmap _ (Cons n) = Cons n
+
+instance Applicative Column where
+   pure _ = Cons []
+   Cons ns <*> Cons ms = Cons (ns++ms)
+-}
 
 atom :: Atom.C a => Int -> T a
 atom i = Cons [i]
diff --git a/src/Graphics/Gnuplot/Value/Tuple.hs b/src/Graphics/Gnuplot/Value/Tuple.hs
--- a/src/Graphics/Gnuplot/Value/Tuple.hs
+++ b/src/Graphics/Gnuplot/Value/Tuple.hs
@@ -4,8 +4,9 @@
 
 Maybe we add a method for the binary interface to gnuplot later.
 -}
-module Graphics.Gnuplot.Value.Tuple
-   (C(text, number),
+module Graphics.Gnuplot.Value.Tuple (
+   C(text, columnCount),
+   ColumnCount(ColumnCount),
    ) where
 
 import System.Locale (defaultTimeLocale, )
@@ -17,16 +18,43 @@
 
 
 class C a where
+   {- |
+   For values that are also in Atom class,
+   'text' must generate a singleton list.
+   -}
    text :: a -> [ShowS]
+
    {- |
-   The right pair member is a dummy result
-   that is needed only for type inference.
-   Expect that it is undefined
+   It must hold @ColumnCount (length (text x)) == columnCount@.
    -}
-   number :: (Int, a)
-   number = (1, error "gnuplot: dummy tuple value")
+   columnCount :: ColumnCount a
+   columnCount = ColumnCount 1
 
+{- |
+Count numbers of gnuplot data columns for the respective type.
 
+Somehow a writer monad with respect to Sum monoid
+without material monadic result.
+
+Cf. ColumnSet module.
+-}
+newtype ColumnCount a = ColumnCount Int
+   deriving (Eq, Ord, Show)
+
+{-
+Functor and Applicative instances would be useful
+for combining column sets,
+but they are dangerous, because they can bring
+type and column columnCount out of sync.
+-}
+
+pure :: a -> ColumnCount a
+pure _ = ColumnCount 0
+
+(<*>) :: ColumnCount (a -> b) -> ColumnCount a -> ColumnCount b
+ColumnCount n <*> ColumnCount m = ColumnCount (n+m)
+
+
 singleton :: a -> [a]
 singleton = (:[])
 
@@ -55,24 +83,24 @@
 
 instance (C a, C b) => C (a,b) where
    text (a,b) = text a ++ text b
-   number =
-      let (na,a) = number
-          (nb,b) = number
-      in  (na+nb, (a,b))
+   columnCount =
+      pure (,)
+         <*> columnCount
+         <*> columnCount
 
 instance (C a, C b, C c) => C (a,b,c) where
    text (a,b,c) = text a ++ text b ++ text c
-   number =
-      let (na,a) = number
-          (nb,b) = number
-          (nc,c) = number
-      in  (na+nb+nc, (a,b,c))
+   columnCount =
+      pure (,,)
+         <*> columnCount
+         <*> columnCount
+         <*> columnCount
 
 instance (C a, C b, C c, C d) => C (a,b,c,d) where
    text (a,b,c,d) = text a ++ text b ++ text c ++ text d
-   number =
-      let (na,a) = number
-          (nb,b) = number
-          (nc,c) = number
-          (nd,d) = number
-      in  (na+nb+nc+nd, (a,b,c,d))
+   columnCount =
+      pure (,,,)
+         <*> columnCount
+         <*> columnCount
+         <*> columnCount
+         <*> columnCount
