gnuplot 0.3.4 → 0.5.7
raw patch · 57 files changed
Files
- Changes.md +15/−0
- Makefile +16/−4
- data/runtime.data +52/−0
- execute/shell/Graphics/Gnuplot/Execute.hs +4/−3
- execute/tmp/Graphics/Gnuplot/Execute.hs +12/−4
- gnuplot.cabal +76/−33
- src/Demo.hs +189/−45
- src/Graphics/Gnuplot/Advanced.hs +91/−20
- src/Graphics/Gnuplot/ColorSpecification.hs +307/−0
- src/Graphics/Gnuplot/Display.hs +3/−55
- src/Graphics/Gnuplot/Encoding.hs +53/−0
- src/Graphics/Gnuplot/File.hs +17/−0
- src/Graphics/Gnuplot/Frame.hs +6/−8
- src/Graphics/Gnuplot/Frame/Option.hs +39/−6
- src/Graphics/Gnuplot/Frame/OptionSet.hs +213/−30
- src/Graphics/Gnuplot/Frame/OptionSet/Histogram.hs +61/−0
- src/Graphics/Gnuplot/Frame/OptionSet/Style.hs +26/−0
- src/Graphics/Gnuplot/Graph.hs +3/−0
- src/Graphics/Gnuplot/Graph/ThreeDimensional.hs +6/−28
- src/Graphics/Gnuplot/Graph/TwoDimensional.hs +33/−14
- src/Graphics/Gnuplot/LineSpecification.hs +1/−0
- src/Graphics/Gnuplot/MultiPlot.hs +18/−9
- src/Graphics/Gnuplot/Plot.hs +3/−0
- src/Graphics/Gnuplot/Plot/ThreeDimensional.hs +44/−12
- src/Graphics/Gnuplot/Plot/TwoDimensional.hs +88/−32
- src/Graphics/Gnuplot/Private/ColorSpecification.hs +22/−0
- src/Graphics/Gnuplot/Private/Command.hs +28/−0
- src/Graphics/Gnuplot/Private/Display.hs +56/−0
- src/Graphics/Gnuplot/Private/Encoding.hs +11/−0
- src/Graphics/Gnuplot/Private/File.hs +4/−0
- src/Graphics/Gnuplot/Private/Frame.hs +4/−10
- src/Graphics/Gnuplot/Private/FrameOption.hs +97/−18
- src/Graphics/Gnuplot/Private/FrameOptionSet.hs +83/−22
- src/Graphics/Gnuplot/Private/Graph.hs +6/−1
- src/Graphics/Gnuplot/Private/Graph2D.hs +53/−24
- src/Graphics/Gnuplot/Private/Graph2DType.hs +125/−0
- src/Graphics/Gnuplot/Private/Graph3D.hs +66/−26
- src/Graphics/Gnuplot/Private/Graph3DType.hs +38/−0
- src/Graphics/Gnuplot/Private/GraphEmpty.hs +4/−1
- src/Graphics/Gnuplot/Private/GraphType.hs +0/−61
- src/Graphics/Gnuplot/Private/LineSpecification.hs +8/−1
- src/Graphics/Gnuplot/Private/Plot.hs +87/−36
- src/Graphics/Gnuplot/Private/Terminal.hs +19/−0
- src/Graphics/Gnuplot/Simple.hs +181/−105
- src/Graphics/Gnuplot/Terminal.hs +2/−17
- src/Graphics/Gnuplot/Terminal/Default.hs +21/−0
- src/Graphics/Gnuplot/Terminal/PNG.hs +16/−4
- src/Graphics/Gnuplot/Terminal/PostScript.hs +43/−10
- src/Graphics/Gnuplot/Terminal/QT.hs +53/−0
- src/Graphics/Gnuplot/Terminal/SVG.hs +17/−4
- src/Graphics/Gnuplot/Terminal/WXT.hs +53/−0
- src/Graphics/Gnuplot/Terminal/X11.hs +5/−5
- src/Graphics/Gnuplot/Time.hs +1/−2
- src/Graphics/Gnuplot/Utility.hs +41/−3
- src/Graphics/Gnuplot/Value/Atom.hs +54/−0
- src/Graphics/Gnuplot/Value/ColumnSet.hs +38/−0
- src/Graphics/Gnuplot/Value/Tuple.hs +118/−0
+ Changes.md view
@@ -0,0 +1,15 @@+# Change log for the `gnuplot` Haskell binding++## 0.5.7:++ * `Gnuplot.Terminal.QT`++ * `Gnuplot.Execute`:+ Do longer call `pgnuplot` on Windows.+ It is gone in gnuplot-5.0 in January 2015.++## 0.5.5:++ * `Gnuplot.Utility.quote` bugfix:+ Do not escape printable non-ASCII characters+ because gnuplot has no universal escaping support for Unicode codepoints.
Makefile view
@@ -1,14 +1,26 @@ ghci: ghci-tmp ghci-tmp:- ghci -Wall -i:src:execute/tmp src/Graphics/Gnuplot/Simple.hs+ ghci -Wall -i:src:dist/build/autogen:execute/tmp src/Graphics/Gnuplot/Simple.hs ghci-pipe:- ghci -Wall -i:src:execute/pipe src/Graphics/Gnuplot/Simple.hs+ ghci -Wall -i:src:dist/build/autogen:execute/pipe src/Graphics/Gnuplot/Simple.hs ghci-shell:- ghci -Wall -i:src:execute/shell src/Graphics/Gnuplot/Simple.hs+ ghci -Wall -i:src:dist/build/autogen:execute/shell src/Graphics/Gnuplot/Simple.hs ghci-demo:- ghci -Wall -i:src:execute/tmp src/Demo.hs+ ghci -Wall -i:src:dist/build/autogen:execute/tmp src/Demo.hs +testbuild:+ runhaskell Setup configure --user -f buildExamples+ runhaskell Setup build+ runhaskell Setup haddock++ runhaskell Setup clean+ runhaskell Setup configure --user -f executePipe+ runhaskell Setup build++ runhaskell Setup clean+ runhaskell Setup configure --user -f executeShell+ runhaskell Setup build
+ data/runtime.data view
@@ -0,0 +1,52 @@+#description: runtimes over input size+1 6.355182636689504e-5+100 1.0948364162371856e-2+199 2.2883437011933076e-2+298 3.6984818514001545e-2+397 5.278430392525412e-2+496 6.556876441607734e-2+595 8.094012753488622e-2+694 9.764933499422945e-2+793 0.11376420890800729+892 0.1303682446197088+991 0.1494559487429532+1090 0.16847618759261968+1189 0.1870789716535227+1288 0.20706133347400274+1387 0.22577923641544467+1486 0.24842725050880543+1585 0.2687356359522487+1684 0.29853175822408823+1783 0.30569358846083045+1882 0.34811570598277525+1981 0.37377121156830634+2080 0.3976917936986544+2179 0.4248938615564355+2278 0.4563135662584595+2377 0.4827751635322885+2476 0.5078150705665049+2575 0.5308599307954707+2674 0.5731755964461464+2773 0.5953289658030824+2872 0.6123024067073677+2971 0.5644368814660525+3070 0.6892736894713817+3169 0.7198984790477585+3268 0.75820146082337+3367 0.7922666002868061+3466 0.8332174605827827+3565 0.8727248373231685+3664 0.9070082204645331+3763 0.941051246582755+3862 0.9763012261824174+3961 1.0146614115691386+4060 1.053540654379474+4159 1.1035736989768552+4258 1.1434341162864607+4357 1.1855544921484864+4456 0.935738517553156+4555 1.2367099547145342+4654 1.2909424329951484+4753 1.3264400538531225+4852 1.3685529705611144+4951 1.4105760332671073
execute/shell/Graphics/Gnuplot/Execute.hs view
@@ -1,9 +1,10 @@ module Graphics.Gnuplot.Execute where +import Graphics.Gnuplot.Utility (semiColonConcat, )++import Shell.Utility.Quote as Quote import System.Exit (ExitCode, ) import System.Cmd (system, )-import Graphics.Gnuplot.Utility- (quote, semiColonConcat, ) simple ::@@ -12,7 +13,7 @@ -> IO ExitCode simple program options = let cmd =- "sh -c 'echo " ++ quote (semiColonConcat program) +++ "sh -c 'echo " ++ Quote.minimal (semiColonConcat program) ++ " | gnuplot " ++ unwords options ++ "'" in do --putStrLn cmd system cmd
execute/tmp/Graphics/Gnuplot/Execute.hs view
@@ -1,7 +1,9 @@ module Graphics.Gnuplot.Execute where +import qualified System.IO as IO+import System.IO.Temp (withSystemTempFile, ) import System.Exit (ExitCode, )-import System.Cmd (rawSystem, )+import System.Process (readProcessWithExitCode, ) tmpScript :: FilePath@@ -12,6 +14,12 @@ -> [String] {-^ Options for gnuplot -} -> IO ExitCode simple program options =- do writeFile tmpScript (unlines program)- -- putStrLn cmd- rawSystem "gnuplot" $ options ++ [tmpScript]+ withSystemTempFile tmpScript $ \path handle -> do+ IO.hPutStr handle (unlines program)+ IO.hClose handle+ -- putStrLn $ showCommandForUser "gnuplot" (options ++ [path])+ (exitCode, _out, _err) <-+ readProcessWithExitCode "gnuplot" (options ++ [path]) []+ -- putStr out+ -- putStr err+ return exitCode
gnuplot.cabal view
@@ -1,6 +1,7 @@+Cabal-Version: 2.2 Name: gnuplot-Version: 0.3.4-License: BSD3+Version: 0.5.7+License: BSD-3-Clause License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de> Maintainer: Henning Thielemann <haskell@henning-thielemann.de>@@ -12,8 +13,9 @@ This is a wrapper to gnuplot which lets you create 2D and 3D plots. .- Start a simple session with @make ghci@.- This loads the module "Graphics.Gnuplot.Simple"+ Start a simple session with @cabal repl@.+ If not already loaded, call @:module Graphics.Gnuplot.Simple@+ in order to load "Graphics.Gnuplot.Simple" which is ready for use in GHCi. It does not address all fancy gnuplot features in order to stay simple.@@ -22,27 +24,36 @@ I recommend "Graphics.Gnuplot.Advanced". This module contains also an overview of the hierarchy of objects.+ . Examples for using this interface can be found in the "Demo" module.+ In order to compile this and install an example data file,+ use the Cabal flag @buildExamples@: .+ > $ cabal install -fbuildExamples gnuplot+ . With the Cabal flags executePipe and executeShell you can switch to more convenient but probably less portable ways of feeding gnuplot with a script.-Tested-With: GHC==6.8.2-Cabal-Version: >=1.2+ .+ Alternative packages: @plot@, @HPlot@, @Chart@, @textPlot@, @easyplot@+Tested-With: GHC==7.4.2, GHC==7.6.3, GHC==7.8.4, GHC==7.10.3+Tested-With: GHC==8.2.1, GHC==8.6.5 Build-Type: Simple Extra-Source-Files: Makefile- execute/tmp/Graphics/Gnuplot/Execute.hs- execute/pipe/Graphics/Gnuplot/Execute.hs- execute/shell/Graphics/Gnuplot/Execute.hs+ Changes.md+Data-Files:+ data/runtime.data -Flag splitBase- description: Choose the new smaller, split-up base package.+Source-Repository this+ Tag: 0.5.7+ Type: darcs+ Location: http://code.haskell.org/gnuplot/ -Flag buildTests- description: Build test executables- default: False+Source-Repository head+ Type: darcs+ Location: http://code.haskell.org/gnuplot/ Flag buildExamples description: Build example executables@@ -58,20 +69,21 @@ Library Build-Depends:- array >= 0.1 && <0.4,- containers >= 0.1 && <0.4,- utility-ht >= 0.0.1 && < 0.1,- monoid-transformer >= 0.0.2 && <0.1- If flag(splitBase)- Build-Depends:- base >= 2 && <6,- process >= 1.0 && < 1.1,- time >= 1.1 && < 1.2,- old-locale >= 1.0 && < 1.1- Else- Build-Depends:- base >= 1.0 && < 2+ filepath >=1.1 && <1.5,+ temporary >=1.1 && <1.4,+ array >=0.1 && <0.6,+ containers >=0.1 && <0.7,+ utility-ht >=0.0.12 && <0.1,+ data-accessor-transformers >=0.2.1 && <0.3,+ data-accessor >=0.2.2 && <0.3,+ transformers >=0.3 && <0.7,+ semigroups >=0.1 && <1.0,+ deepseq >=1.0 && <1.5,+ process >=1.0 && <1.7,+ time >=1.5 && <1.14,+ base >=2 && <5 + Default-Language: Haskell98 GHC-Options: -Wall Hs-Source-Dirs: src@@ -80,6 +92,7 @@ Else If flag(executeShell) Hs-Source-Dirs: execute/shell+ Build-Depends: shell-utility >=0.0 && <0.2 Else Hs-Source-Dirs: execute/tmp @@ -87,38 +100,68 @@ Graphics.Gnuplot.Simple Graphics.Gnuplot.Time Graphics.Gnuplot.Advanced+ Graphics.Gnuplot.Display+ Graphics.Gnuplot.File+ Graphics.Gnuplot.Terminal+ Graphics.Gnuplot.Terminal.Default Graphics.Gnuplot.Terminal.PostScript Graphics.Gnuplot.Terminal.PNG Graphics.Gnuplot.Terminal.SVG+ Graphics.Gnuplot.Terminal.WXT+ Graphics.Gnuplot.Terminal.QT Graphics.Gnuplot.Terminal.X11+ Graphics.Gnuplot.Encoding Graphics.Gnuplot.Frame Graphics.Gnuplot.Frame.Option Graphics.Gnuplot.Frame.OptionSet+ Graphics.Gnuplot.Frame.OptionSet.Style+ Graphics.Gnuplot.Frame.OptionSet.Histogram+ Graphics.Gnuplot.Plot Graphics.Gnuplot.Plot.TwoDimensional Graphics.Gnuplot.Plot.ThreeDimensional+ Graphics.Gnuplot.Graph Graphics.Gnuplot.Graph.TwoDimensional Graphics.Gnuplot.Graph.ThreeDimensional Graphics.Gnuplot.LineSpecification+ Graphics.Gnuplot.ColorSpecification Graphics.Gnuplot.MultiPlot+ Graphics.Gnuplot.Value.Atom+ Graphics.Gnuplot.Value.Tuple+ Graphics.Gnuplot.Value.ColumnSet Other-Modules: Graphics.Gnuplot.Private.LineSpecification+ Graphics.Gnuplot.Private.ColorSpecification Graphics.Gnuplot.Private.Plot Graphics.Gnuplot.Private.Frame Graphics.Gnuplot.Private.FrameOption Graphics.Gnuplot.Private.FrameOptionSet- Graphics.Gnuplot.Private.GraphType Graphics.Gnuplot.Private.Graph Graphics.Gnuplot.Private.Graph2D Graphics.Gnuplot.Private.Graph3D+ Graphics.Gnuplot.Private.Graph2DType+ Graphics.Gnuplot.Private.Graph3DType Graphics.Gnuplot.Private.GraphEmpty+ Graphics.Gnuplot.Private.Terminal+ Graphics.Gnuplot.Private.Encoding+ Graphics.Gnuplot.Private.Display+ Graphics.Gnuplot.Private.File+ Graphics.Gnuplot.Private.Command Graphics.Gnuplot.Utility Graphics.Gnuplot.Execute- Graphics.Gnuplot.Display- Graphics.Gnuplot.Terminal Executable gnuplot-demo- If !flag(buildExamples)+ If flag(buildExamples)+ Build-Depends:+ gnuplot,+ time,+ array,+ filepath,+ utility-ht,+ base+ Else Buildable: False+ Default-Language: Haskell98 GHC-Options: -Wall- Hs-Source-Dirs: src, execute/tmp- Main-Is: Demo.hs+ Main-Is: src/Demo.hs+ Other-Modules: Paths_gnuplot+ Autogen-Modules: Paths_gnuplot
src/Demo.hs view
@@ -1,81 +1,225 @@ module Main where -import qualified Graphics.Gnuplot.Advanced as Plot-import qualified Graphics.Gnuplot.Terminal.X11 as X11+import qualified Graphics.Gnuplot.Advanced as GP 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+ import qualified Graphics.Gnuplot.Plot.ThreeDimensional as Plot3D+import qualified Graphics.Gnuplot.Graph.ThreeDimensional as Graph3D import qualified Graphics.Gnuplot.Plot.TwoDimensional as Plot2D import qualified Graphics.Gnuplot.Graph.TwoDimensional as Graph2D import Graphics.Gnuplot.Plot.TwoDimensional (linearScale, ) +import qualified Graphics.Gnuplot.LineSpecification as LineSpec+import Graphics.Gnuplot.Value.Tuple (Label(Label))++import qualified Data.Time as Time++import qualified Paths_gnuplot as Path+import System.FilePath ((</>), )++import Control.Monad (liftM2, ) import Data.Array (listArray, )-import Data.Monoid (mappend, )+import Data.Foldable (foldMap, )+import Data.Monoid (mappend, mconcat, )+import Data.Tuple.HT (mapFst) -simple2d :: Plot2D.T+simple2d :: Plot2D.T Double Double simple2d =- Plot2D.function (linearScale 100 (-10,10::Double)) sin+ Plot2D.function Graph2D.lines+ (linearScale 100 (-10,10)) sin -circle2d :: Plot2D.T+circle2d :: Plot2D.T Double Double circle2d =- fmap- (Graph2D.typ Graph2D.points)- (Plot2D.parameterFunction- (linearScale 24 (-pi,pi::Double))- (\t -> (cos t, sin t)))+ Plot2D.parameterFunction Graph2D.lines+ (linearScale 24 (-pi,pi))+ (\t -> (cos t, sin t)) -overlay2d :: Frame.T Graph2D.T+list2d :: Plot2D.T Int Integer+list2d =+ Plot2D.list Graph2D.listPoints [0,1,1,2,3,5,8,13]++labels2d :: Plot2D.T Double Double+labels2d =+ Plot2D.list Graph2D.labels $+ flip map [1..12] $+ \t -> (let w = fromInteger t*2*pi/12 in (sin w, cos w), Label $ show t)++candle2d :: Plot2D.T Time.Day Double+candle2d =+ Plot2D.list Graph2D.candleSticks $+ zip [(Time.fromGregorian 2008 01 01) ..] $+ flip map (linearScale 32 (0,2*pi)) $+ \t -> (-sin t, -2*sin t, 2*sin t, sin t)++image2d :: Plot2D.T Double Double+image2d =+ case linearScale 300 (-20,20) of+ xs ->+ Plot2D.function Graph2D.image (liftM2 (,) xs xs) $+ \(x,y) -> cos (sqrt (x*x+x*y+y*y))++overlay2d :: Frame.T (Graph2D.T Double Double) overlay2d =- Frame.cons (Opts.size 1 0.4 $ Opts.remove Opt.key $ Opts.deflt) $- Plot2D.function (linearScale 100 (-pi,pi::Double)) cos+ Frame.cons (Opts.size 1 0.4 $ defltOpts) $+ Plot2D.function Graph2D.lines (linearScale 100 (-pi,pi)) cos `mappend` circle2d -multiplot2d :: MultiPlot.T-multiplot2d =- let opts :: Opts.T graph- opts =- Opts.remove Opt.key $+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.keyOutside $+ Opts.xTicks2d+ [("220", 0), ("320", 1), ("420", 2), ("520", 3), ("620", 4), ("720", 5)] $+ Opts.deflt) $+ foldMap (\(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 =+ let domain = (-10,10)+ frameOpts =+ Opts.xRange2d domain $+ Opts.yRange2d (-1.5,1.5) $ Opts.deflt- (prefix,suffix) =+ in Frame.cons frameOpts $+ Plot2D.functionsWithLineSpec Graph2D.lines (linearScale 100 domain) $+ map (mapFst (flip LineSpec.title LineSpec.deflt)) $+ ("sin", sin) :+ ("cos", cos) :+ ("tan", tan) :+ []++filled2d :: Frame.T (Graph2D.T Double Double)+filled2d =+ let scale = linearScale 100 (-10,10)+ wave style (lower,upper) =+ Plot2D.function style scale $+ (\y -> (lower*y, upper*y)) . sin+ in Frame.cons (Opts.key False Opts.deflt) $ mconcat $+ wave Graph2D.filledStripeAbove (1.0, 1.3) :+ wave Graph2D.filledStripeBelow (1.0, 1.3) :+ wave Graph2D.filledStripe (0.7, 1.0) :+ []++file2d :: FilePath -> FilePath -> Frame.T (Graph2D.T Int Double)+file2d path file =+ let lineSpec =+ Graph2D.lineSpec $+ LineSpec.title "runtimes" $+ LineSpec.lineWidth 2.5 $+ LineSpec.deflt+ frameOpts =+ Opts.xLabel "input size" $+ Opts.yLabel "runtime (ms)" $+ Opts.title ("Graph from " ++ file) $+ Opts.deflt+ in Frame.cons frameOpts $ fmap lineSpec $+ Plot2D.pathFromFile Graph2D.lines (path </> file) 1 2++mixed2d :: MultiPlot.T+mixed2d =+ MultiPlot.simpleFromPartArray $+ listArray ((0,0), (0,2)::(Int,Int)) $+ MultiPlot.partFromPlot circle2d :+ MultiPlot.partFromFrame+ (Frame.cons (Opts.sizeSquare $ Opts.xFormat "%m-%d" $ defltOpts) $+ candle2d) :+ MultiPlot.partFromPlot list2d :+ []++{-+The size settings of overlay2d interfer badly with the other plots,+because 'unset' does not restore the size to the multiplot settings.+-}+size2d :: MultiPlot.T+size2d =+ MultiPlot.simpleFromPartArray $+ listArray ((0,0), (0,2)::(Int,Int)) $+ MultiPlot.partFromPlot candle2d :+ MultiPlot.partFromFrame+ (Frame.cons (Opts.yLabel "Fibonacci" $ defltOpts) list2d) :+ MultiPlot.partFromPlot candle2d :+ []++defltOpts :: Graph.C graph => Opts.T graph+defltOpts = Opts.key False $ Opts.deflt++wave3d :: Frame.T (Graph3D.T Double Double Double)+wave3d =+ let meshNodes = linearScale 20 (-2,2)+ in Frame.cons+ (Opts.grid True $+ Opts.view 42 17 1 1 $+ Opts.xRange3d (-2.5,2.5) $+ Opts.yRange3d (-2.5,2.5) $+ defltOpts) $+ Plot3D.surface meshNodes meshNodes (\x y -> cos(x*x+y*y))++lissajous3d :: Frame.T (Graph3D.T Double Double Double)+lissajous3d =+ let t = linearScale 300 (-pi, pi)+ f n = map (sin . (*) n) t+ in Frame.cons defltOpts $+ Plot3D.cloud Graph3D.lines $+ zip3 (f 3) (f 4) (f 9)++multiplot :: MultiPlot.T+multiplot =+ let (prefix,suffix) = splitAt 7 $ map MultiPlot.partFromFrame $ map (\k ->- Frame.cons (Opts.xRange (-1,1) opts) $- Plot2D.parameterFunction+ Frame.cons (Opts.xRange2d (-1,1) defltOpts) $+ Plot2D.parameterFunction Graph2D.lines (linearScale 48 (-pi,pi::Double)) (\t -> (cos (t + pi/7*fromInteger k), sin (2*t)))) $ [0..13]- meshNodes = linearScale 20 (-2,2::Double)-{-- center =- MultiPlot.partFromFrame $- Frame.empty--}- center =- MultiPlot.partFromFrame $- Frame.cons- (Opts.xRange (-2.5,2.5) $- Opts.yRange (-2.5,2.5) $- opts) $- (Plot3D.function- meshNodes meshNodes- (\x y -> cos(x*x+y*y)))- in MultiPlot.simpleFromPartArray $- listArray ((0::Int,0::Int), (2,4)) $+-- center = MultiPlot.partFromFrame Frame.empty+ center = MultiPlot.partFromFrame wave3d+ in MultiPlot.title "multiplot of 2d and 3d graphics" $+ MultiPlot.simpleFromPartArray $+ listArray ((0,0), (2,4)::(Int,Int)) $ prefix ++ center : suffix main :: IO ()-main =- do Plot.plot X11.cons simple2d- Plot.plot X11.cons overlay2d- Plot.plot X11.cons multiplot2d- return ()+main = sequence_ $+ GP.plotDefault simple2d :+ GP.plotDefault list2d :+ GP.plotDefault labels2d :+ GP.plotDefault candle2d :+ GP.plotDefault image2d :+ GP.plotDefault histogram2d :+ GP.plotDefault names2d :+ GP.plotDefault filled2d :+ GP.plotDefault overlay2d :+ (GP.plotDefault . flip file2d "runtime.data"+ =<< fmap (</> "data") Path.getDataDir) :+ GP.plotDefault mixed2d :+ GP.plotDefault size2d :+ GP.plotDefault wave3d :+ GP.plotDefault lissajous3d :+ GP.plotDefault multiplot :+ []
src/Graphics/Gnuplot/Advanced.hs view
@@ -34,7 +34,7 @@ of learning gnuplot script syntax, it happens frequently that people ask, how to express a certain gnuplot script using this package.-Thus let's annotate the gnuplot script generated by @Demo.multiplot2d@+Thus let's annotate the gnuplot script generated by @Demo.multiplot@ in order to show, what belongs to where: > # the terminal selection is part of the 'plot' command of this module@@ -71,20 +71,29 @@ -} module Graphics.Gnuplot.Advanced ( plot,+ plotDefault,+ plotSync,+ plotAsync,+ fileContents, ) where import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet-import qualified Graphics.Gnuplot.Display as Display--import qualified Graphics.Gnuplot.Terminal as Terminal-import qualified Graphics.Gnuplot.Execute as Exec+import qualified Graphics.Gnuplot.Private.Display as Display+import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import qualified Graphics.Gnuplot.Terminal.Default as DefaultTerm+import qualified Graphics.Gnuplot.File as File +import qualified Graphics.Gnuplot.Private.Command as Cmd+import Control.Concurrent (ThreadId, forkIO, ) import System.Exit (ExitCode, )-import Data.Monoid (Monoid, ) -- for Haddock-import qualified Data.Monoid.State as State-import Data.List (intersperse, ) +import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS+import Data.Monoid (Monoid, mempty, )+import Control.Functor.HT (void, )+import Data.Tuple.HT (mapFst, ) + -- * User front-end @@ -95,24 +104,86 @@ For interactive sessions, better use "Graphics.Gnuplot.Simple". @gfx@ must be one of the types @Plot@, @Frame@, @MultiPlot@.++This function runs gnuplot asynchronously+for interactive terminals (X11, WX)+and synchronously for file terminals (PostScript, PNG, etc.).+This emulates the behaviour of @gnuplot --persist@.+However, when running asynchronous+we cannot obtain a real 'ExitCode'.+Thus, in this case we will always return 'ExitSuccess'. -} plot :: (Terminal.C terminal, Display.C gfx) => terminal -> gfx -> IO ExitCode plot term gfx =+ case Terminal.canonical term of+ cterm ->+ Cmd.asyncIfInteractive+ (Terminal.interactive cterm)+ (plotCore cterm gfx)++plotAsync ::+ (Terminal.C terminal, Display.C gfx) =>+ terminal -> gfx -> IO ThreadId+plotAsync term gfx = forkIO $ void $ plotSync term gfx++plotSync ::+ (Terminal.C terminal, Display.C gfx) =>+ terminal -> gfx -> IO ExitCode+plotSync = plotCore . Terminal.canonical++plotCore ::+ (Display.C gfx) =>+ Terminal.T -> gfx -> IO ExitCode+plotCore term gfx =+ Cmd.run $ render term gfx++{- |+Return the gnuplot script and the curve files+corresponding to your plot data.+The first parameter is the directory where the curve files are located.+This directory is baked into the gnuplot script+and the paths of the curve files.++Don't make any assumptions about the structure of the files.+Feeding the files to gnuplot, archiving them or study them+are the intended uses of them.+-}+fileContents ::+ (Terminal.C terminal, Display.C gfx) =>+ FilePath -> terminal -> gfx -> (String, [File.T])+fileContents dir term gfx =+ mapFst unlines $ render (Terminal.canonical term) gfx dir++render ::+ Display.C gfx =>+ Terminal.T -> gfx -> FilePath -> ([String], [File.T])+render term gfx dir = let body =- State.evaluate (0, OptionSet.decons OptionSet.deflt) $+ flip MR.runReader dir $+ flip MS.evalStateT (0, OptionSet.initial) $ Display.runScript $ Display.toScript gfx- in do mapM_ Display.writeData (Display.files body)- Exec.simple- (formatTerminal term : Display.commands body)- ["-persist"]+ in (Terminal.format term ++ Display.commands body,+ Display.files body) -formatTerminal ::- (Terminal.C terminal) =>- terminal -> String-formatTerminal term =- let (Terminal.Cons options commands) = Terminal.canonical term- in concat $ intersperse "; " $- ("set terminal " ++ unwords options) : commands++{- |+Plot using the default gnuplot terminal.+-}+plotDefault ::+ (Display.C gfx) =>+ gfx -> IO ExitCode+plotDefault =+ plot DefaultTerm.cons++{-+In the module introduction we refer to Monoid.+That is we must import Monoid module in order to make Haddock happy.+On the other hand we do not use Monoid in the module body,+thus GHC emits a warning.+This dummy declaration makes both GHC and Haddock happy.+-}+_haddockDummy :: Monoid a => a+_haddockDummy = mempty
+ src/Graphics/Gnuplot/ColorSpecification.hs view
@@ -0,0 +1,307 @@+module Graphics.Gnuplot.ColorSpecification (+ T,+ rgb,+ rgb8,+ name,+ paletteFrac,++ white,+ black,+ gray0,+ grey0,+ gray10,+ grey10,+ gray20,+ grey20,+ gray30,+ grey30,+ gray40,+ grey40,+ gray50,+ grey50,+ gray60,+ grey60,+ gray70,+ grey70,+ gray80,+ grey80,+ gray90,+ grey90,+ gray100,+ grey100,+ gray,+ grey,+ lightGray,+ lightGrey,+ darkGray,+ darkGrey,+ red,+ lightRed,+ darkRed,+ yellow,+ lightYellow,+ darkYellow,+ green,+ lightGreen,+ darkGreen,+ springGreen,+ forestGreen,+ seaGreen,+ blue,+ lightBlue,+ darkBlue,+ midnightBlue,+ navy,+ mediumBlue,+ royalblue,+ skyblue,+ cyan,+ lightCyan,+ darkCyan,+ magenta,+ lightMagenta,+ darkMagenta,+ turquoise,+ lightTurquoise,+ darkTurquoise,+ pink,+ lightPink,+ darkPink,+ coral,+ lightCoral,+ orangeRed,+ salmon,+ lightSalmon,+ darkSalmon,+ aquamarine,+ khaki,+ darkKhaki,+ goldenrod,+ lightGoldenrod,+ darkGoldenrod,+ gold,+ beige,+ brown,+ orange,+ darkOrange,+ violet,+ darkViolet,+ plum,+ purple,++ ) where++import qualified Graphics.Gnuplot.Private.ColorSpecification as Color+import Graphics.Gnuplot.Private.ColorSpecification (T, )+import Data.Ord.HT (limit, )+import Data.Word (Word8, )+++{- |+Color components for Red, Green, Blue, must be in the range @[0,1]@.+-}+rgb :: Double -> Double -> Double -> T+rgb r g b =+ rgb8 (word8FromDouble r) (word8FromDouble g) (word8FromDouble b)++word8FromDouble :: Double -> Word8+word8FromDouble c =+ round (limit (0,1) c * 255)++rgb8 :: Word8 -> Word8 -> Word8 -> T+rgb8 = Color.RGB8++paletteFrac :: Double -> T+paletteFrac = Color.PaletteFrac++{- |+Specify a color by name.+You are responsible for choosing an existing name in gnuplot.+If your color is available as Haskell variable in this module,+then prefer this one.+-}+name :: String -> T+name = Color.Name+++{-+This function chooses how we represent below colors in gnuplot.+If we use RGB values then we stay independent from the available color names+in the current gnuplot version.+If we use color names, then the generated gnuplot scripts are more readable.+-}+makeColor :: String -> Int -> Word8 -> Word8 -> Word8 -> T+makeColor str _ _ _ _ = name str+++white,+ black,+ gray0,+ grey0,+ gray10,+ grey10,+ gray20,+ grey20,+ gray30,+ grey30,+ gray40,+ grey40,+ gray50,+ grey50,+ gray60,+ grey60,+ gray70,+ grey70,+ gray80,+ grey80,+ gray90,+ grey90,+ gray100,+ grey100,+ gray,+ grey,+ lightGray,+ lightGrey,+ darkGray,+ darkGrey,+ red,+ lightRed,+ darkRed,+ yellow,+ lightYellow,+ darkYellow,+ green,+ lightGreen,+ darkGreen,+ springGreen,+ forestGreen,+ seaGreen,+ blue,+ lightBlue,+ darkBlue,+ midnightBlue,+ navy,+ mediumBlue,+ royalblue,+ skyblue,+ cyan,+ lightCyan,+ darkCyan,+ magenta,+ lightMagenta,+ darkMagenta,+ turquoise,+ lightTurquoise,+ darkTurquoise,+ pink,+ lightPink,+ darkPink,+ coral,+ lightCoral,+ orangeRed,+ salmon,+ lightSalmon,+ darkSalmon,+ aquamarine,+ khaki,+ darkKhaki,+ goldenrod,+ lightGoldenrod,+ darkGoldenrod,+ gold,+ beige,+ brown,+ orange,+ darkOrange,+ violet,+ darkViolet,+ plum,+ purple :: T++{-+gnuplot> show colornames+-}++white = makeColor "white" 0xffffff 255 255 255+black = makeColor "black" 0x000000 0 0 0+gray0 = makeColor "gray0" 0x000000 0 0 0+grey0 = makeColor "grey0" 0x000000 0 0 0+gray10 = makeColor "gray10" 0x1a1a1a 26 26 26+grey10 = makeColor "grey10" 0x1a1a1a 26 26 26+gray20 = makeColor "gray20" 0x333333 51 51 51+grey20 = makeColor "grey20" 0x333333 51 51 51+gray30 = makeColor "gray30" 0x4d4d4d 77 77 77+grey30 = makeColor "grey30" 0x4d4d4d 77 77 77+gray40 = makeColor "gray40" 0x666666 102 102 102+grey40 = makeColor "grey40" 0x666666 102 102 102+gray50 = makeColor "gray50" 0x7f7f7f 127 127 127+grey50 = makeColor "grey50" 0x7f7f7f 127 127 127+gray60 = makeColor "gray60" 0x999999 153 153 153+grey60 = makeColor "grey60" 0x999999 153 153 153+gray70 = makeColor "gray70" 0xb3b3b3 179 179 179+grey70 = makeColor "grey70" 0xb3b3b3 179 179 179+gray80 = makeColor "gray80" 0xcccccc 204 204 204+grey80 = makeColor "grey80" 0xcccccc 204 204 204+gray90 = makeColor "gray90" 0xe5e5e5 229 229 229+grey90 = makeColor "grey90" 0xe5e5e5 229 229 229+gray100 = makeColor "gray100" 0xffffff 255 255 255+grey100 = makeColor "grey100" 0xffffff 255 255 255+gray = makeColor "gray" 0xbebebe 190 190 190+grey = makeColor "grey" 0xbebebe 190 190 190+lightGray = makeColor "light-gray" 0xd3d3d3 211 211 211+lightGrey = makeColor "light-grey" 0xd3d3d3 211 211 211+darkGray = makeColor "dark-gray" 0xa9a9a9 169 169 169+darkGrey = makeColor "dark-grey" 0xa9a9a9 169 169 169+red = makeColor "red" 0xff0000 255 0 0+lightRed = makeColor "light-red" 0xf03232 240 50 50+darkRed = makeColor "dark-red" 0x8b0000 139 0 0+yellow = makeColor "yellow" 0xffff00 255 255 0+lightYellow = makeColor "light-yellow" 0xffffe0 255 255 224+darkYellow = makeColor "dark-yellow" 0xc8c800 200 200 0+green = makeColor "green" 0x00ff00 0 255 0+lightGreen = makeColor "light-green" 0x90ee90 144 238 144+darkGreen = makeColor "dark-green" 0x006400 0 100 0+springGreen = makeColor "spring-green" 0x00ff7f 0 255 127+forestGreen = makeColor "forest-green" 0x228b22 34 139 34+seaGreen = makeColor "sea-green" 0x2e8b57 46 139 87+blue = makeColor "blue" 0x0000ff 0 0 255+lightBlue = makeColor "light-blue" 0xadd8e6 173 216 230+darkBlue = makeColor "dark-blue" 0x00008b 0 0 139+midnightBlue = makeColor "midnight-blue" 0x191970 25 25 112+navy = makeColor "navy" 0x000080 0 0 128+mediumBlue = makeColor "medium-blue" 0x0000cd 0 0 205+royalblue = makeColor "royalblue" 0x4169e1 65 105 225+skyblue = makeColor "skyblue" 0x87ceeb 135 206 235+cyan = makeColor "cyan" 0x00ffff 0 255 255+lightCyan = makeColor "light-cyan" 0xe0ffff 224 255 255+darkCyan = makeColor "dark-cyan" 0x008b8b 0 139 139+magenta = makeColor "magenta" 0xff00ff 255 0 255+lightMagenta = makeColor "light-magenta" 0xf055f0 240 85 240+darkMagenta = makeColor "dark-magenta" 0x8b008b 139 0 139+turquoise = makeColor "turquoise" 0x40e0d0 64 224 208+lightTurquoise = makeColor "light-turquoise" 0xafeeee 175 238 238+darkTurquoise = makeColor "dark-turquoise" 0x00ced1 0 206 209+pink = makeColor "pink" 0xffc0cb 255 192 203+lightPink = makeColor "light-pink" 0xffb6c1 255 182 193+darkPink = makeColor "dark-pink" 0xff1493 255 20 147+coral = makeColor "coral" 0xff7f50 255 127 80+lightCoral = makeColor "light-coral" 0xf08080 240 128 128+orangeRed = makeColor "orange-red" 0xff4500 255 69 0+salmon = makeColor "salmon" 0xfa8072 250 128 114+lightSalmon = makeColor "light-salmon" 0xffa07a 255 160 122+darkSalmon = makeColor "dark-salmon" 0xe9967a 233 150 122+aquamarine = makeColor "aquamarine" 0x7fffd4 127 255 212+khaki = makeColor "khaki" 0xf0e68c 240 230 140+darkKhaki = makeColor "dark-khaki" 0xbdb76b 189 183 107+goldenrod = makeColor "goldenrod" 0xdaa520 218 165 32+lightGoldenrod = makeColor "light-goldenrod" 0xeedd82 238 221 130+darkGoldenrod = makeColor "dark-goldenrod" 0xb8860b 184 134 11+gold = makeColor "gold" 0xffd700 255 215 0+beige = makeColor "beige" 0xf5f5dc 245 245 220+brown = makeColor "brown" 0xa52a2a 165 42 42+orange = makeColor "orange" 0xffa500 255 165 0+darkOrange = makeColor "dark-orange" 0xff8c00 255 140 0+violet = makeColor "violet" 0xee82ee 238 130 238+darkViolet = makeColor "dark-violet" 0x9400d3 148 0 211+plum = makeColor "plum" 0xdda0dd 221 160 221+purple = makeColor "purple" 0xa020f0 160 32 240
src/Graphics/Gnuplot/Display.hs view
@@ -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
+ src/Graphics/Gnuplot/Encoding.hs view
@@ -0,0 +1,53 @@+{- |+Support for special characters++Gnuplot has no universal Unicode escaping mechanism,+you can only work with encodings.+However, not all terminals support all encodings,+not all terminals even support utf-8.+Some terminals seem to support only one encoding.+E.g. WX seems to support only UTF-8,+X11 seems to support only Latin-1.+Postscript, SVG, PNG seem to support both UTF-8 and Latin-1.++The @gnuplot@ Haskell bindings+always write using the system-wide default encoding.+Thus it is better not to set an encoding other than 'locale' explicitly.+However, if you write the files yourself in a certain encoding+you should use the @encoding@ option of the according terminal.+-}+module Graphics.Gnuplot.Encoding (+ T,+ locale, deflt,+ iso_8859_1, iso_8859_15, iso_8859_2, iso_8859_9,+ koi8r, koi8u,+ cp437, cp850, cp852, cp950, cp1250, cp1251, cp1254,+ sjis, utf8,+ ) where++import Graphics.Gnuplot.Private.Encoding (T(Cons))+++locale, deflt,+ iso_8859_1, iso_8859_15, iso_8859_2, iso_8859_9,+ koi8r, koi8u,+ cp437, cp850, cp852, cp950, cp1250, cp1251, cp1254,+ sjis, utf8 :: T++locale = Cons "locale"+deflt = Cons "default"+iso_8859_1 = Cons "iso_8859_1"+iso_8859_15 = Cons "iso_8859_15"+iso_8859_2 = Cons "iso_8859_2"+iso_8859_9 = Cons "iso_8859_9"+koi8r = Cons "koi8r"+koi8u = Cons "koi8u"+cp437 = Cons "cp437"+cp850 = Cons "cp850"+cp852 = Cons "cp852"+cp950 = Cons "cp950"+cp1250 = Cons "cp1250"+cp1251 = Cons "cp1251"+cp1254 = Cons "cp1254"+sjis = Cons "sjis"+utf8 = Cons "utf8"
+ src/Graphics/Gnuplot/File.hs view
@@ -0,0 +1,17 @@+module Graphics.Gnuplot.File (T(Cons, name, content), write) where++import qualified Graphics.Gnuplot.Private.File as File++data T =+ Cons {+ name :: FilePath,+ content :: String+ }+ deriving (Show, Eq)+++write :: T -> IO ()+write (Cons fn cont) = writeFile fn cont++instance File.C T where+ write = write
src/Graphics/Gnuplot/Frame.hs view
@@ -3,20 +3,18 @@ cons, simple, empty, ) where +import qualified Graphics.Gnuplot.Frame.OptionSet as OptionSet import qualified Graphics.Gnuplot.Private.Frame as Frame import qualified Graphics.Gnuplot.Private.Plot as Plot-import qualified Graphics.Gnuplot.Private.FrameOptionSet as Option import qualified Graphics.Gnuplot.Private.GraphEmpty as Empty--import qualified Data.Monoid.State as State+import qualified Graphics.Gnuplot.Private.Graph as Graph -cons :: Option.T graph -> Plot.T graph -> Frame.T graph+cons :: OptionSet.T graph -> Plot.T graph -> Frame.T graph cons = Frame.Cons -simple :: Plot.T graph -> Frame.T graph-simple = cons Option.deflt+simple :: Graph.C graph => Plot.T graph -> Frame.T graph+simple = cons OptionSet.deflt empty :: Frame.T Empty.T-empty =- simple (Plot.Cons (State.pure []))+empty = simple $ Plot.pure []
src/Graphics/Gnuplot/Frame/Option.hs view
@@ -1,9 +1,42 @@ 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,++ xLogScale,+ yLogScale,+ zLogScale,++ 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
src/Graphics/Gnuplot/Frame/OptionSet.hs view
@@ -1,73 +1,185 @@ module Graphics.Gnuplot.Frame.OptionSet ( OptionSet.T,- OptionSet.deflt,+ deflt, OptionSet.add, OptionSet.remove,+ OptionSet.boolean,+ OptionSet.addBool, size,+ sizeRatio,+ sizeSquare, title,- xRange,- yRange,- zRange,+ key,+ keyInside,+ keyOutside,+ xRange2d,+ yRange2d,+ xRange3d,+ yRange3d,+ zRange3d, xLabel, yLabel, zLabel,+ xTicks2d,+ yTicks2d,+ xTicks3d,+ yTicks3d,+ zTicks3d,+ xLogScale,+ yLogScale,+ zLogScale,+ grid,+ gridXTicks,+ gridYTicks,+ gridZTicks,+ xFormat,+ yFormat,+ zFormat, view, viewMap,++ boxwidthRelative,+ boxwidthAbsolute, ) where import qualified Graphics.Gnuplot.Graph.ThreeDimensional as Graph3D+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.Private.Graph as Graph +import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Graphics.Gnuplot.Value.Tuple as Tuple+ import Graphics.Gnuplot.Private.FrameOptionSet (T, ) -import Graphics.Gnuplot.Utility- (quote, )+import Graphics.Gnuplot.Utility (quote, commaConcat, ) +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] +sizeRatio :: Graph.C graph => Double -> T graph -> T graph+sizeRatio r =+ OptionSet.add Option.sizeRatio ["ratio", show r]++sizeSquare :: Graph.C graph => T graph -> T graph+sizeSquare =+ OptionSet.add Option.sizeRatio ["square"]+ 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 +keyInside :: Graph.C graph => T graph -> T graph+keyInside = OptionSet.add Option.keyPosition ["inside"]++keyOutside :: Graph.C graph => T graph -> T graph+keyOutside = OptionSet.add Option.keyPosition ["outside"]++{- xRange :: Graph.C graph => (Double, Double) -> T graph -> T graph xRange = range Option.xRange yRange :: Graph.C graph => (Double, Double) -> T graph -> T graph yRange = range Option.yRange -zRange :: (Double, Double) -> T Graph3D.T -> T Graph3D.T+zRange :: (Double, Double) -> T (Graph3D.T x y z) -> T (Graph3D.T x y z) zRange = range Option.zRange+-} -range :: Graph.C graph => Option.T -> (Double, Double) -> T graph -> T graph+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.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.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.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.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.zRangeBounds+++range ::+ (Atom.C a, Tuple.C a, Graph.C graph) =>+ Option.T -> (a, a) -> T graph -> T graph range opt (x,y) =- OptionSet.add opt ["[" ++ show x ++ ":" ++ show y ++ "]"]+ OptionSet.add opt+ [showString "[" . atomText x .+ showString ":" . atomText y $+ "]"] +atomText ::+ (Atom.C a, Tuple.C a) =>+ a -> ShowS+atomText x =+ case Tuple.text x of+ [s] -> s+ _ -> error "OptionSet.fromSingleton: types of Atom class must generate single representation texts" + 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 :: String -> T Graph3D.T -> T Graph3D.T-zLabel = label Option.zLabel+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.zLabelText label :: Graph.C graph => Option.T -> String -> T graph -> T graph label opt x = OptionSet.add opt [quote x] +xFormat :: Graph.C graph => String -> T graph -> T graph+xFormat = format Option.xFormat++yFormat :: Graph.C graph => String -> T graph -> T graph+yFormat = format Option.yFormat++zFormat ::+ (Atom.C x, Atom.C y, Atom.C z) =>+ String -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+zFormat = format Option.zFormat++format :: Graph.C graph => Option.T -> String -> T graph -> T graph+format opt x =+ OptionSet.add opt [quote x]++ {- | Set parameters of viewing a surface graph. See <info:gnuplot/view>@@ -77,34 +189,105 @@ Double {- ^ rotateZ -} -> Double {- ^ scale -} -> Double {- ^ scaleZ -} ->- T Graph3D.T -> T Graph3D.T+ T (Graph3D.T x y z) -> T (Graph3D.T x y z) view rotateX rotateZ scale scaleZ =- OptionSet.add Option.view [show rotateX, show rotateZ, show scale, show scaleZ]+ OptionSet.add Option.view+ [commaConcat [show rotateX, show rotateZ, show scale, show scaleZ]] {- | Show flat pixel map. -}-viewMap :: T Graph3D.T -> T Graph3D.T+viewMap :: T (Graph3D.T x y z) -> T (Graph3D.T x y z) 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 -> T Graph3D.T-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]+++xLogScale :: Graph.C graph => T graph -> T graph+xLogScale = OptionSet.add Option.xLogScale []++yLogScale :: Graph.C graph => T graph -> T graph+yLogScale = OptionSet.add Option.yLogScale []++zLogScale ::+ (Atom.C x, Atom.C y, Atom.C z) =>+ T (Graph3D.T x y z) -> T (Graph3D.T x y z)+zLogScale = OptionSet.add Option.zLogScale []+++grid :: Graph.C graph => Bool -> T graph -> T graph+grid b =+ OptionSet.addBool Option.gridXTicks b .+ OptionSet.addBool Option.gridYTicks b .+ OptionSet.addBool Option.gridZTicks b++gridXTicks :: Graph.C graph => Bool -> T graph -> T graph+gridXTicks = OptionSet.addBool Option.gridXTicks++gridYTicks :: Graph.C graph => Bool -> T graph -> T graph+gridYTicks = OptionSet.addBool Option.gridYTicks++gridZTicks ::+ (Atom.C x, Atom.C y, Atom.C z) =>+ Bool -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+gridZTicks = OptionSet.addBool Option.gridZTicks+++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 -> T Graph3D.T+cornerToColor :: CornersToColor -> T (Graph3D.T x y z) -> T (Graph3D.T x y z) -type3d :: Plot3dType -> T Graph3D.T -> T Graph3D.T+type3d :: Plot3dType -> T (Graph3D.T x y z) -> T (Graph3D.T x y z) -}
+ src/Graphics/Gnuplot/Frame/OptionSet/Histogram.hs view
@@ -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"]
+ src/Graphics/Gnuplot/Frame/OptionSet/Style.hs view
@@ -0,0 +1,26 @@+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.addBool Option.styleFillSolid True++fillBorder :: Graph.C graph => Bool -> T graph -> T graph+fillBorder =+ OptionSet.addBool Option.styleFillBorder++fillBorderLineType :: Graph.C graph => Int -> T graph -> T graph+fillBorderLineType n =+ OptionSet.add Option.styleFillBorder ["border", show n]
+ src/Graphics/Gnuplot/Graph.hs view
@@ -0,0 +1,3 @@+module Graphics.Gnuplot.Graph (Graph.C) where++import qualified Graphics.Gnuplot.Private.Graph as Graph
src/Graphics/Gnuplot/Graph/ThreeDimensional.hs view
@@ -2,39 +2,17 @@ T, Type, - defaultType,- deflt,+-- deflt, - typ, lineSpec, - lines,- points,- linesPoints, impulses,- dots,- steps,- fSteps,- hiSteps,- errorBars,- xErrorBars,- yErrorBars,- xyErrorBars,- errorLines,- xErrorLines,- yErrorLines,- xyErrorLines,- boxes,- filledCurves,- boxErrorBars,- boxXYErrorBars,- financeBars,- candleSticks, vectors,- pm3d,+ Graph3DType.pm3d,++ Graph3DType.lines,+ points, ) where import Graphics.Gnuplot.Private.Graph3D-import Graphics.Gnuplot.Private.GraphType hiding (T, )--import Prelude hiding (lines, )+import Graphics.Gnuplot.Private.Graph3DType as Graph3DType hiding (T, )
src/Graphics/Gnuplot/Graph/TwoDimensional.hs view
@@ -2,13 +2,32 @@ T, Type, - defaultType,- deflt,+-- deflt, - typ, lineSpec, - lines,+ listLines,+ listPoints,+ listLinesPoints,+ listImpulses,+ listDots,+ histograms,++ xErrorBarsRelative,+ yErrorBarsRelative,+ xyErrorBarsRelative,+ xErrorBarsAbsolute,+ yErrorBarsAbsolute,+ xyErrorBarsAbsolute,++ xErrorLinesRelative,+ yErrorLinesRelative,+ xyErrorLinesRelative,+ xErrorLinesAbsolute,+ yErrorLinesAbsolute,+ xyErrorLinesAbsolute,++ Graph2DType.lines, points, linesPoints, impulses,@@ -17,24 +36,24 @@ fSteps, hiSteps, errorBars,- xErrorBars,- yErrorBars,- xyErrorBars, errorLines,- xErrorLines,- yErrorLines,- xyErrorLines, boxes, filledCurves,+{- boxErrorBars, boxXYErrorBars,+-} financeBars, candleSticks, vectors,- -- pm3d,+ image,++ filledStripe,+ filledStripeAbove,+ filledStripeBelow,++ labels, ) where import Graphics.Gnuplot.Private.Graph2D-import Graphics.Gnuplot.Private.GraphType hiding (T, )--import Prelude hiding (lines, )+import Graphics.Gnuplot.Private.Graph2DType as Graph2DType hiding (T, )
src/Graphics/Gnuplot/LineSpecification.hs view
@@ -6,6 +6,7 @@ lineStyle, lineType, lineWidth,+ lineColor, pointType, pointSize, title,
src/Graphics/Gnuplot/MultiPlot.hs view
@@ -5,24 +5,27 @@ 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 import Data.Monoid (mconcat, )+import Data.Foldable (foldMap, ) 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,20 +63,26 @@ 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.pure $+ Display.Body []+ ["set multiplot layout " +++ show (numRows mp) ++ ", " ++ show (numColumns mp) +++ foldMap ((" title " ++) . quote) (title_ mp)]) : (map scriptFromPart $ parts mp) ++- (Display.Script $ State.pure $+ (Display.pure $ Display.Body [] ["unset multiplot"]) : []
+ src/Graphics/Gnuplot/Plot.hs view
@@ -0,0 +1,3 @@+module Graphics.Gnuplot.Plot (T) where++import Graphics.Gnuplot.Private.Plot (T)
src/Graphics/Gnuplot/Plot/ThreeDimensional.hs view
@@ -1,35 +1,67 @@ module Graphics.Gnuplot.Plot.ThreeDimensional (+ T,+ cloud,+-- function,+ mesh,+ surface,+ linearScale,- module Graphics.Gnuplot.Plot.ThreeDimensional,+ functionToGraph, ) where +import qualified Graphics.Gnuplot.Private.Graph3DType as Type import qualified Graphics.Gnuplot.Private.Graph3D as Graph import qualified Graphics.Gnuplot.Private.Plot as Plot+-- import qualified Graphics.Gnuplot.Value.ColumnSet as Col+import qualified Graphics.Gnuplot.Value.Tuple as Tuple+import qualified Graphics.Gnuplot.Value.Atom as Atom import Graphics.Gnuplot.Utility- (showTriplet, linearScale, )+ (functionToGraph, linearScale, assembleCells, ) import Data.List.HT (outerProduct, ) {- |-Plots can be assembled using 'mappend' or 'mconcat'.+Plots can be assembled using 'mappend' or 'mconcat'+or several functions from "Data.Foldable". -}-type T = Plot.T Graph.T+type T x y z = Plot.T (Graph.T x y z) -- * computed plots -mesh ::- (Show a, Show b, Show c) =>- [[(a,b,c)]] -> T-mesh dat =+cloud ::+ (Atom.C x, Atom.C y, Atom.C z,+ Tuple.C a) =>+ Type.T x y z a -> [a] -> T x y z+cloud typ ps = Plot.withUniqueFile- (unlines (map (unlines . map showTriplet) dat))- [Graph.deflt (Graph.Dim3 1 2 3)]+ (assembleCells (map Tuple.text ps))+ [Graph.deflt typ+ [1 .. case Type.tupleSize typ of Tuple.ColumnCount n -> n]] +{- function ::- (Show a, Show b, Show c) =>- [b] -> [c] -> (b -> c -> a) -> T+ (Atom.C x, Atom.C y, Atom.C z) =>+ Type.T (x,y,z) -> [x] -> [y] -> (x -> y -> z) -> T function xArgs yArgs f =+ cloud (liftM2 (\x y -> (x, y, f x y)) xArgs yArgs)+-}+++mesh ::+ (Atom.C x, Atom.C y, Atom.C z,+ Tuple.C x, Tuple.C y, Tuple.C z) =>+ [[(x,y,z)]] -> T x y z+mesh pss =+ Plot.withUniqueFile+ (assembleCells (concatMap (\ps -> map Tuple.text ps ++ [[]]) pss))+ [Graph.pm3d]++surface ::+ (Atom.C x, Atom.C y, Atom.C z,+ Tuple.C x, Tuple.C y, Tuple.C z) =>+ [x] -> [y] -> (x -> y -> z) -> T x y z+surface xArgs yArgs f = mesh (outerProduct (\x y -> (x, y, f x y)) xArgs yArgs)
src/Graphics/Gnuplot/Plot/TwoDimensional.hs view
@@ -1,73 +1,129 @@ -- shall this also export Graph.Type, set plotType and so on? module Graphics.Gnuplot.Plot.TwoDimensional (+ T,++ list,+ function,+ functions,+ functionsWithLineSpec,+ parameterFunction,++ listFromFile,+ pathFromFile,+ linearScale,- module Graphics.Gnuplot.Plot.TwoDimensional,+ functionToGraph, ) where +import qualified Graphics.Gnuplot.Private.Graph2DType as Type import qualified Graphics.Gnuplot.Private.Graph2D as Graph import qualified Graphics.Gnuplot.Private.Plot as Plot+import qualified Graphics.Gnuplot.Private.LineSpecification as LineSpec+import qualified Graphics.Gnuplot.Value.ColumnSet as Col+import qualified Graphics.Gnuplot.Value.Tuple as Tuple+import qualified Graphics.Gnuplot.Value.Atom as Atom import Graphics.Gnuplot.Utility- (functionToGraph, commaConcat, linearScale, )+ (functionToGraph, linearScale, assembleCells, ) import qualified Data.List.Match as Match+import qualified Data.List.HT as ListHT {- | Plots can be assembled using 'mappend' or 'mconcat'.+You can alter attributes of embedded graphs using 'fmap'. -}-type T = Plot.T Graph.T+type T x y = Plot.T (Graph.T x y) -- * computed plots {- |-> list (take 30 (let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs))+> list Type.listLines (take 30 (let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs))+> list Type.lines (take 30 (let fibs0 = 0 : fibs1; fibs1 = 1 : zipWith (+) fibs0 fibs1 in zip fibs0 fibs1)) -}-list :: Show a => [a] -> T-list dat =+list ::+ (Atom.C x, Atom.C y, Tuple.C a) =>+ Type.T x y a -> [a] -> T x y+list typ ps = Plot.withUniqueFile- (unlines (map show dat))- ([Graph.deflt (Graph.Dim1 1)])+ (assembleCells (map Tuple.text ps))+ [Graph.deflt typ+ [1 .. case Type.tupleSize typ of Tuple.ColumnCount n -> n]] {- |-> function (linearScale 1000 (-10,10)) sin+> function Type.line (linearScale 1000 (-10,10)) sin -}-function :: Show a => [a] -> (a -> a) -> T-function args f =- path (functionToGraph args f)+function ::+ (Atom.C x, Atom.C y,+ Tuple.C a, Tuple.C b) =>+ Type.T x y (a,b) -> [a] -> (a -> b) -> T x y+function typ args f =+ list typ (functionToGraph args f) {- |-> functions (linearScale 1000 (-10,10)) [sin, cos]+> functions Type.line (linearScale 1000 (-10,10)) [sin, cos] -}-functions :: Show a => [a] -> [a -> a] -> T-functions args fs =- let dat = map (\x -> (x, map ($ x) fs)) args+functions ::+ (Atom.C x, Atom.C y,+ Tuple.C a, Tuple.C b) =>+ Type.T x y (a,b) -> [a] -> [a -> b] -> T x y+functions typ args =+ functionsWithLineSpec typ args . map ((,) LineSpec.deflt)++{- |+> functionsWithLineSpec Type.line (linearScale 1000 (-10,10)) $+> map (mapFst (flip LineSpec.title LineSpec.deflt)) [("sin", sin), ("cos", cos)]+-}+functionsWithLineSpec ::+ (Atom.C x, Atom.C y,+ Tuple.C a, Tuple.C b) =>+ Type.T x y (a,b) -> [a] -> [(LineSpec.T, a -> b)] -> T x y+functionsWithLineSpec typ args fs =+ let dat = map (\x -> (x, map (($ x) . snd) fs)) args+ mapType :: (a -> b) -> Type.T x y a -> Type.T x y b+ mapType _ (Type.Cons str) = Type.Cons str+ Tuple.ColumnCount na = Type.tupleSize $ mapType fst typ+ Tuple.ColumnCount nb = Type.tupleSize $ mapType snd typ in Plot.withUniqueFile- (unlines (map (commaConcat . map show . uncurry (:)) dat))+ (assembleCells+ (map (\(a,b) -> Tuple.text a ++ concatMap Tuple.text b) dat)) (Match.take fs $- map (Graph.deflt . Graph.Dim2 1) [2..])+ zipWith+ (\(lineSpec,_f) ns ->+ Graph.lineSpec lineSpec $ Graph.deflt typ ([1..na] ++ ns))+ fs $+ ListHT.sliceVertical nb [(na+1)..]) -path :: Show a => [(a,a)] -> T-path dat =- Plot.withUniqueFile- (unlines (map (\(x,y) -> show x ++ ", " ++ show y) dat))- ([Graph.deflt (Graph.Dim2 1 2)]) {- |-> parameterFunction (linearScale 1000 (0,2*pi)) (\t -> (sin (2*t), cos t))+> parameterFunction Type.line (linearScale 1000 (0,2*pi)) (\t -> (sin (2*t), cos t)) -}-parameterFunction :: Show a => [a] -> (a -> (a,a)) -> T-parameterFunction args f = path (map f args)+parameterFunction ::+ (Atom.C x, Atom.C y,+ Tuple.C a) =>+ Type.T x y a -> [t] -> (t -> a) -> T x y+parameterFunction typ args f = list typ (map f args) -- * plot stored data -listFromFile :: FilePath -> Int -> T-listFromFile filename column =- Plot.fromGraphs filename [Graph.deflt (Graph.Dim1 column)]+fromFile ::+ (Atom.C x, Atom.C y) =>+ Type.T x y a -> FilePath -> Col.T a -> T x y+fromFile typ filename (Col.Cons cs) =+ Plot.fromGraphs filename [Graph.deflt typ cs] -pathFromFile :: FilePath -> Int -> Int -> T-pathFromFile filename columnX columnY =- Plot.fromGraphs filename [Graph.deflt (Graph.Dim2 columnX columnY)]+listFromFile ::+ (Atom.C i, Atom.C y) =>+ Type.T i y y -> FilePath -> Int -> T i y+listFromFile typ filename column =+ fromFile typ filename (Col.atom column)++pathFromFile ::+ (Atom.C x, Atom.C y) =>+ Type.T x y (x,y) -> FilePath -> Int -> Int -> T x y+pathFromFile typ filename columnX columnY =+ fromFile typ filename (Col.pair (Col.atom columnX) (Col.atom columnY))
+ src/Graphics/Gnuplot/Private/ColorSpecification.hs view
@@ -0,0 +1,22 @@+module Graphics.Gnuplot.Private.ColorSpecification where++import Graphics.Gnuplot.Utility (quote, )+import Data.List.HT (padLeft, )+import Data.Word (Word8, )+import Numeric (showHex, )+++data T =+ Name String+ | RGB8 {red, green, blue :: Word8}+ | PaletteFrac Double+++toString :: T -> String+toString c =+ case c of+ Name name -> "rgbcolor " ++ quote name+ RGB8 r g b ->+ "rgbcolor #" +++ concatMap (padLeft '0' 2 . flip showHex "") [r,g,b]+ PaletteFrac frac -> "palette frac " ++ show frac
+ src/Graphics/Gnuplot/Private/Command.hs view
@@ -0,0 +1,28 @@+module Graphics.Gnuplot.Private.Command where++import qualified Graphics.Gnuplot.Private.File as File+import qualified Graphics.Gnuplot.Execute as Exec+import System.Exit (ExitCode(ExitSuccess), )+import Control.Concurrent (forkIO, )++import System.IO.Temp (withSystemTempDirectory, )++import Control.DeepSeq (deepseq, )+import Control.Functor.HT (void, )+++run ::+ (File.C file) =>+ (FilePath -> ([String], [file])) -> IO ExitCode+run render =+ withSystemTempDirectory "gnuplot" $ \dir ->+ case render dir of+ (cmds, files) -> deepseq cmds $ do+ mapM_ File.write files+ Exec.simple (cmds ++ ["pause mouse close"]) []++asyncIfInteractive :: Bool -> IO ExitCode -> IO ExitCode+asyncIfInteractive interactive act =+ if interactive+ then fmap (const ExitSuccess) $ forkIO $ void act+ else act
+ src/Graphics/Gnuplot/Private/Display.hs view
@@ -0,0 +1,56 @@+module Graphics.Gnuplot.Private.Display where++import qualified Graphics.Gnuplot.Private.FrameOption as Option+import qualified Graphics.Gnuplot.File as File++import qualified Data.Map as Map+import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS+import Control.Monad (liftM2, return, )+import Data.Monoid (Monoid, mempty, mappend, )+import Data.Semigroup (Semigroup, (<>), )++import Prelude (FilePath, String, Int, ($), (.), )+++newtype Script =+ Script {+ runScript :: MS.StateT (Int, OptionSet) (MR.Reader FilePath) Body+ }++pure :: Body -> Script+pure = Script . return++data Body =+ Body {+ files :: [File.T],+ commands :: [String]+ }++type OptionSet = Map.Map Option.T [String]+++instance Semigroup Script where+ Script b0 <> Script b1 = Script (liftM2 (<>) b0 b1)++{-+Could also be implemented with Control.Monad.Trans.State:+mappend = liftA2 mappend+-}+instance Monoid Script where+ mempty = Script $ return mempty+ mappend = (<>)++instance Semigroup Body where+ Body f0 c0 <> Body f1 c1 = Body (f0 <> f1) (c0 <> c1)++{-+Could also be implemented with Control.Monad.Trans.State:+mappend = liftA2 mappend+-}+instance Monoid Body where+ mempty = Body mempty mempty+ mappend = (<>)++class C gfx where+ toScript :: gfx -> Script
+ src/Graphics/Gnuplot/Private/Encoding.hs view
@@ -0,0 +1,11 @@+module Graphics.Gnuplot.Private.Encoding where++import Graphics.Gnuplot.Utility (listFromMaybeWith)++newtype T = Cons String++format :: T -> String+format (Cons enc) = "set encoding " ++ enc++formatMaybe :: Maybe T -> [String]+formatMaybe = listFromMaybeWith format
+ src/Graphics/Gnuplot/Private/File.hs view
@@ -0,0 +1,4 @@+module Graphics.Gnuplot.Private.File where++class C file where+ write :: file -> IO ()
src/Graphics/Gnuplot/Private/Frame.hs view
@@ -3,11 +3,10 @@ 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-import Data.Monoid (Monoid, mappend, )+import Data.Monoid (mappend, ) data T graph =@@ -18,11 +17,6 @@ instance Graph.C graph => Display.C (T graph) where toScript frame =- (Display.Script $- State.Cons $ \(n, opts0) ->- let opts1 = option frame- in (Display.Body [] $- OptionSet.diffToString (OptionSet.Cons opts0) opts1,- (n, OptionSet.decons opts1)))+ (Plot.optionsToScript $ option frame) `mappend`- (Display.toScript $ plot frame)+ (Plot.toScript $ plot frame)
src/Graphics/Gnuplot/Private/FrameOption.hs view
@@ -1,27 +1,106 @@+{- |+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.+E.g. you can write @set grid xtics@ and @set grid noxtics@,+but both commands refer to the same internal boolean variable,+that we like to call @xtics@.+It is important that the gnuplot Haskell bindings know+that these two set commands refer to the same gnuplot state,+since we want to simulate a stateless functional interface+in front of a stateful imperative one.++In case of a such a hidden state,+we manage an identifier in the second field of 'T'.+It is mainly used for distinguishing different hidden states,+that are accessed by the same @set@ variable.+This second field may not contain valid gnuplot identifiers,+however you might use the field for formatting boolean options+using 'Graphics.Gnuplot.Frame.OptionSet.addBool'.+-}+data T = Cons String String deriving (Eq, Ord, Show) -custom :: String -> T+{- |+Constructs a generic option from Strings for the first and second field of 'T'.++This is very flexible, but not very safe.+Use it only as fall-back,+if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet".+-}+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"++xLogScale :: T; xLogScale = Cons "logscale x" ""+yLogScale :: T; yLogScale = Cons "logscale y" ""+zLogScale :: T; zLogScale = Cons "logscale z" ""+++title :: T; title = Cons "title" ""+view :: T; view = Cons "view" ""++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"+sizeRatio :: T; sizeRatio = size "ratio"+keyShow :: T; keyShow = key "show"+keyPosition :: T; keyPosition = key "position"++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"++gridXTicks :: T; gridXTicks = grid "xtics"+gridYTicks :: T; gridYTicks = grid "ytics"+gridZTicks :: T; gridZTicks = grid "ztics"++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" ""
src/Graphics/Gnuplot/Private/FrameOptionSet.hs view
@@ -11,6 +11,7 @@ module Graphics.Gnuplot.Private.FrameOptionSet where import qualified Graphics.Gnuplot.Private.FrameOption as Option+import Graphics.Gnuplot.Utility (formatBool, ) import qualified Data.Map as Map @@ -18,33 +19,57 @@ import Data.Maybe (mapMaybe, ) +type Plain = Map.Map Option.T [String]+ newtype T graph =- Cons {decons :: Map.Map Option.T [String]}+ Cons {decons :: Plain} + {- | The default options contain what we expect as default value in gnuplot.-We need an entry for every option-that cannot be reset by @unset@.+We need an entry for every option that cannot be reset by @unset@. -}-deflt :: T graph+deflt :: Plain deflt =- Cons $ Map.fromList $- (Option.key, []) :- (Option.border, []) :- (Option.xLabel, []) :- (Option.yLabel, []) :- (Option.zLabel, []) :- (Option.xRange, ["[*:*]"]) :- (Option.yRange, ["[*:*]"]) :- (Option.zRange, ["[*:*]"]) :- (Option.xTicks, []) :- (Option.yTicks, []) :- (Option.zTicks, []) :+ Map.fromList $+ (Option.keyShow, []) :+-- (Option.border, []) :+ (Option.sizeRatio, ["noratio"]) :+ (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.gridXTicks, ["noxtics"]) :+ (Option.gridYTicks, ["noytics"]) :+ (Option.gridZTicks, ["noztics"]) :+ (Option.styleFillSolid, ["0"]) :+ (Option.styleFillBorder, []) :+ (Option.styleHistogram, ["clustered"]) :+-- (Option.timeFmt, [quote "%s"]) :+ (Option.boxwidth, []) : [] +initial :: Plain+initial =+ flip Map.union deflt $+ Map.fromList $+ (Option.xData, []) :+ (Option.yData, []) :+ (Option.zData, []) :+-- (Option.timeFmt, []) :+ [] {- |-Add an option with arguments as plain strings.+Add (set) an option with arguments as plain strings.+ This is very flexible, but not very safe. Use it only as fall-back, if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet".@@ -54,7 +79,11 @@ Cons (Map.insert opt args m) {- |-Remove an option.+Remove (unset) an option.++This is very flexible, but not very safe.+Use it only as fall-back,+if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet". -} remove :: Option.T -> T graph -> T graph remove opt (Cons m) =@@ -64,17 +93,49 @@ Convert the difference between the first and the second option set into a sequence of 'set' and 'unset' commands. -}-diffToString :: T graph -> T graph -> [String]-diffToString (Cons m0) (Cons m1) =+diffToString :: Plain -> Plain -> [String]+diffToString m0 m1 = mapMaybe- (\(Option.Cons opt, (old,new)) ->+ (\(Option.Cons opt _, (old,new)) -> toMaybe (old/=new) $ maybe ("unset " ++ opt)- (\args -> "set " ++ opt ++ " " ++ unwords args)+ (\args -> "set " ++ opt ++ concatMap (' ':) args) new) $ Map.toList $ Map.unionWith (\(old,_) (_,new) -> (old,new)) (fmap (\x -> (Just x, Nothing)) m0) (fmap (\x -> (Nothing, Just x)) m1)++{- |+Set or unset option according to a 'Bool'.+This is for switches that can be disabled using @unset@.++This is very flexible, but not very safe.+Use it only as fall-back,+if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet".++See also: 'addBool', 'add', 'remove'.+-}+boolean :: Option.T -> Bool -> T graph -> T graph+boolean opt on =+ if on+ then add opt []+ else remove opt++{- |+Add an option with boolean value+that is formatted like @set style fill border@ and @set style fill noborder@.+The name of the internal state (i.e. @border@)+must be stored in the second field of the option.++This is very flexible, but not very safe.+Use it only as fall-back,+if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet".++See also 'boolean'.+-}+addBool :: Option.T -> Bool -> T graph -> T graph+addBool opt@(Option.Cons _ state) arg =+ add opt [formatBool state arg]
src/Graphics/Gnuplot/Private/Graph.hs view
@@ -1,5 +1,10 @@ module Graphics.Gnuplot.Private.Graph where +import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet+ class C graph where- command :: graph -> String+ command :: Command graph toString :: graph -> String+ defltOptions :: OptionSet.T graph++newtype Command graph = Command {commandString :: String}
src/Graphics/Gnuplot/Private/Graph2D.hs view
@@ -1,53 +1,82 @@ module Graphics.Gnuplot.Private.Graph2D where +import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet+import qualified Graphics.Gnuplot.Private.FrameOption as Option import qualified Graphics.Gnuplot.Private.LineSpecification as LineSpec-import qualified Graphics.Gnuplot.Private.GraphType as GraphType+import qualified Graphics.Gnuplot.Private.Graph2DType as GraphType import qualified Graphics.Gnuplot.Private.Graph as Graph+import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Data.Map as Map+import qualified Data.List as List import Prelude hiding (lines, ) -data T =+data T x y = Cons {- column_ :: Column,+ column_ :: Columns, type_ :: Type, lineSpec_ :: LineSpec.T } -data Column =- Dim1 {columnX :: Int}- | Dim2 {columnX, columnY :: Int}-+type Columns = [Int] -type Type = GraphType.T+type Type = String -columnToString :: Column -> String-columnToString c =- case c of- Dim1 x -> show x- Dim2 x y -> show x ++ ":" ++ show y+columnToString :: Columns -> String+columnToString =+ concat . List.intersperse ":" . map show -toString :: T -> String+toString :: T x y -> String toString (Cons c t l) = "using " ++ columnToString c ++- " with " ++ GraphType.toString t +++ " with " ++ t ++ " " ++ LineSpec.toString l -instance Graph.C T where- command _ = "plot"- toString = toString +type AxisOption x y a =+ OptionSet.T (T x y) -> Atom.OptionSet a -defaultType :: Type-defaultType = GraphType.lines+defltOptions :: (Atom.C x, Atom.C y) => OptionSet.T (T x y)+defltOptions =+ 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 +++ mk Option.yData Option.yFormat optY +++ (Option.zData, []) :+ (Option.zFormat, []) :+ []+ in result Atom.options Atom.options -deflt :: Column -> T-deflt c = Cons c defaultType LineSpec.deflt +instance (Atom.C x, Atom.C y) => Graph.C (T x y) where+ command = Graph.Command "plot"+ toString = toString+ defltOptions = defltOptions -typ :: Type -> T -> T++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 typ t gr = gr{type_ = t} -lineSpec :: LineSpec.T -> T -> T+{- |+You can alter the line specification of graphs in a plot using 'fmap'.+-}+lineSpec :: LineSpec.T -> T x y -> T x y lineSpec ls gr = gr{lineSpec_ = ls}
+ src/Graphics/Gnuplot/Private/Graph2DType.hs view
@@ -0,0 +1,125 @@+module Graphics.Gnuplot.Private.Graph2DType where++import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Graphics.Gnuplot.Value.Tuple as Tuple+import Graphics.Gnuplot.Value.Tuple (Label)+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 -> Tuple.ColumnCount a+tupleSize _ = Tuple.columnCount+++{-+See info:/gnuplot/set_style_rectangle+-}++listLines :: (Atom.C y) => T Int y y+listPoints :: (Atom.C y) => T Int y y+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)+xyErrorBarsRelative :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,y))+xErrorBarsAbsolute :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,x))+yErrorBarsAbsolute :: (Atom.C x, Atom.C y) => T x y ((x,y),(y,y))+xyErrorBarsAbsolute :: (Atom.C x, Atom.C y) => T x y ((x,y),((x,x),(y,y)))++xErrorLinesRelative :: (Atom.C x, Atom.C y) => T x y ((x,y),x)+yErrorLinesRelative :: (Atom.C x, Atom.C y) => T x y ((x,y),y)+xyErrorLinesRelative :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,y))+xErrorLinesAbsolute :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,x))+yErrorLinesAbsolute :: (Atom.C x, Atom.C y) => T x y ((x,y),(y,y))+xyErrorLinesAbsolute :: (Atom.C x, Atom.C y) => T x y ((x,y),((x,x),(y,y)))++lines :: (Atom.C x, Atom.C y) => T x y (x,y)+points :: (Atom.C x, Atom.C y) => T x y (x,y)+linesPoints :: (Atom.C x, Atom.C y) => T x y (x,y)+impulses :: (Atom.C x, Atom.C y) => T x y (x,y)+dots :: (Atom.C x, Atom.C y) => T x y (x,y)+steps :: (Atom.C x, Atom.C y) => T x y (x,y)+fSteps :: (Atom.C x, Atom.C y) => T x y (x,y)+hiSteps :: (Atom.C x, Atom.C y) => T x y (x,y)+errorBars :: (Atom.C x, Atom.C y) => T x y (x,y)+errorLines :: (Atom.C x, Atom.C y) => T x y (x,y)+boxes :: (Atom.C x, Atom.C y) => T x y (x,y)+filledCurves :: (Atom.C x, Atom.C y) => T x y (x,y)+{-+boxErrorBars :: (Atom.C x, Atom.C y) => T x y (x,y)+boxXYErrorBars :: (Atom.C x, Atom.C y) => T x y (x,y)+-}+financeBars :: (Atom.C x, Atom.C y) => T x y (x,(y,y,y,y))+candleSticks :: (Atom.C x, Atom.C y) => T x y (x,(y,y,y,y))+vectors :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,y))+image :: (Atom.C x, Atom.C y, Atom.C z) => T x y ((x, y), z)++filledStripe :: (Atom.C x, Atom.C y) => T x y (x,(y,y))+filledStripeAbove :: (Atom.C x, Atom.C y) => T x y (x,(y,y))+filledStripeBelow :: (Atom.C x, Atom.C y) => T x y (x,(y,y))++labels :: (Atom.C x, Atom.C y) => T x y ((x,y),Label)+++listLines = Cons "lines"+listPoints = Cons "points"+listLinesPoints = Cons "linespoints"+listImpulses = Cons "impulses"+listDots = Cons "dots"+histograms = Cons "histograms"++xErrorBarsRelative = Cons "xerrorbars"+yErrorBarsRelative = Cons "yerrorbars"+xyErrorBarsRelative = Cons "xyerrorbars"+xErrorBarsAbsolute = Cons "xerrorbars"+yErrorBarsAbsolute = Cons "yerrorbars"+xyErrorBarsAbsolute = Cons "xyerrorbars"++xErrorLinesRelative = Cons "xerrorlines"+yErrorLinesRelative = Cons "yerrorlines"+xyErrorLinesRelative = Cons "xyerrorlines"+xErrorLinesAbsolute = Cons "xerrorlines"+yErrorLinesAbsolute = Cons "yerrorlines"+xyErrorLinesAbsolute = Cons "xyerrorlines"++lines = Cons "lines"+points = Cons "points"+linesPoints = Cons "linespoints"+impulses = Cons "impulses"+dots = Cons "dots"+steps = Cons "steps"+fSteps = Cons "fsteps"+hiSteps = Cons "histeps"+errorBars = Cons "errorbars"+errorLines = Cons "errorlines"+boxes = Cons "boxes"+filledCurves = Cons "filledcurves"+{-+boxErrorBars = Cons "boxerrorbars"+boxXYErrorBars = Cons "boxxyerrorbars"+-}+financeBars = Cons "financebars"+candleSticks = Cons "candlesticks"+vectors = Cons "vectors"+image = Cons "image"++filledStripe = Cons "filledcurves"+filledStripeAbove = Cons "filledcurves above"+filledStripeBelow = Cons "filledcurves below"++labels = Cons "labels"+++toString :: T x y a -> String+toString (Cons t) = t
src/Graphics/Gnuplot/Private/Graph3D.hs view
@@ -1,53 +1,93 @@ module Graphics.Gnuplot.Private.Graph3D where +import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet+import qualified Graphics.Gnuplot.Private.FrameOption as Option import qualified Graphics.Gnuplot.Private.LineSpecification as LineSpec-import qualified Graphics.Gnuplot.Private.GraphType as GraphType+import qualified Graphics.Gnuplot.Private.Graph3DType as GraphType import qualified Graphics.Gnuplot.Private.Graph as Graph+import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Data.Map as Map +import Graphics.Gnuplot.Private.Graph2D (Columns, columnToString, )+ import Prelude hiding (lines, ) -data T =+data T x y z = Cons {- column_ :: Column,+ column_ :: Columns, type_ :: Type, lineSpec_ :: LineSpec.T } -data Column =- Dim3 {columnX, columnY, columnZ :: Int}- | Dim4 {columnX, columnY, columnZ, columnC :: Int}---type Type = GraphType.T+type Type = String -columnToString :: Column -> String-columnToString col =- case col of- Dim3 x y z -> show x ++ ":" ++ show y ++ ":" ++ show z- Dim4 x y z c -> show x ++ ":" ++ show y ++ ":" ++ show z ++ ":" ++ show c--toString :: T -> String+toString :: T x y z -> String toString (Cons c t l) = "using " ++ columnToString c ++- " with " ++ GraphType.toString t +++ " with " ++ t ++ " " ++ LineSpec.toString l -instance Graph.C T where- command _ = "splot"- toString = toString +type AxisOption x y z a =+ OptionSet.T (T x y z) -> Atom.OptionSet a -defaultType :: Type-defaultType = GraphType.pm3d+defltOptions :: (Atom.C x, Atom.C y, Atom.C z) => OptionSet.T (T x y z)+defltOptions =+ 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 +++ mk Option.yData Option.yFormat optY +++ mk Option.yData Option.yFormat optZ +++ []+ in result Atom.options Atom.options Atom.options -deflt :: Column -> T-deflt c = Cons c defaultType LineSpec.deflt +instance (Atom.C x, Atom.C y, Atom.C z) => Graph.C (T x y z) where+ command = Graph.Command "splot"+ toString = toString+ defltOptions = defltOptions -typ :: Type -> T -> T++pm3d :: T x y z+pm3d = Cons (1:2:3:[]) "pm3d" LineSpec.deflt++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 typ t gr = gr{type_ = t} -lineSpec :: LineSpec.T -> T -> T+{-+for 3D plots not all line attributes are supported like:+ pointsize+ pointtype++pm3d and impulses allow:+ linestyle+ linewidth+ linecolor+ linetype+ title++FIXME:+Do we need a separate LineSpec3D type or a type parameter for LineSpec?+-}+lineSpec :: LineSpec.T -> T x y z -> T x y z lineSpec ls gr = gr{lineSpec_ = ls}
+ src/Graphics/Gnuplot/Private/Graph3DType.hs view
@@ -0,0 +1,38 @@+module Graphics.Gnuplot.Private.Graph3DType where++import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Graphics.Gnuplot.Value.Tuple as Tuple++import Prelude hiding (lines, )+++newtype T x y z a = Cons String++tupleSize :: (Tuple.C a) => T x y z a -> Tuple.ColumnCount a+tupleSize _ = Tuple.columnCount+++lines :: (Atom.C x, Atom.C y, Atom.C z) => T x y z (x,y,z)+points :: (Atom.C x, Atom.C y, Atom.C z) => T x y z (x,y,z)++lines = Cons "lines"+points = Cons "points"+++{-+See info:/gnuplot/set_style_rectangle+-}++impulses :: (Atom.C x, Atom.C y, Atom.C z) => T x y z (x,y,z)+vectors :: (Atom.C x, Atom.C y, Atom.C z) => T x y z ((x,y,z), (x,y,z))+pm3d :: (Atom.C x, Atom.C y, Atom.C z) => T x y z (x,y,z)++impulses = Cons "impulses"+vectors = Cons "vectors"+pm3d = Cons "pm3d"++{-# DEPRECATED pm3d "do not use this as graph type, use Graphics.Gnuplot.Plot.ThreeDimensional.surface instead" #-}+++toString :: T x y z a -> String+toString (Cons t) = t
src/Graphics/Gnuplot/Private/GraphEmpty.hs view
@@ -7,11 +7,14 @@ module Graphics.Gnuplot.Private.GraphEmpty where import qualified Graphics.Gnuplot.Private.Graph as Graph+import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet data T = Cons instance Graph.C T where- command _ = "clear"+ command = Graph.Command "clear" toString = const ""+ defltOptions =+ OptionSet.Cons OptionSet.deflt
− src/Graphics/Gnuplot/Private/GraphType.hs
@@ -1,61 +0,0 @@-module Graphics.Gnuplot.Private.GraphType where--import Prelude hiding (lines, )---newtype T = Cons String---lines :: T-points :: T-linesPoints :: T-impulses :: T-dots :: T-steps :: T-fSteps :: T-hiSteps :: T-errorBars :: T-xErrorBars :: T-yErrorBars :: T-xyErrorBars :: T-errorLines :: T-xErrorLines :: T-yErrorLines :: T-xyErrorLines :: T-boxes :: T-filledCurves :: T-boxErrorBars :: T-boxXYErrorBars :: T-financeBars :: T-candleSticks :: T-vectors :: T-pm3d :: T--lines = Cons "lines"-points = Cons "points"-linesPoints = Cons "linespoints"-impulses = Cons "impulses"-dots = Cons "dots"-steps = Cons "steps"-fSteps = Cons "fsteps"-hiSteps = Cons "histeps"-errorBars = Cons "errorbars"-xErrorBars = Cons "xerrorbars"-yErrorBars = Cons "yerrorbars"-xyErrorBars = Cons "xyerrorbars"-errorLines = Cons "errorlines"-xErrorLines = Cons "xerrorlines"-yErrorLines = Cons "yerrorlines"-xyErrorLines = Cons "xyerrorlines"-boxes = Cons "boxes"-filledCurves = Cons "filledcurves"-boxErrorBars = Cons "boxerrorbars"-boxXYErrorBars = Cons "boxxyerrorbars"-financeBars = Cons "financebars"-candleSticks = Cons "candlesticks"-vectors = Cons "vectors"-pm3d = Cons "pm3d"---toString :: T -> String-toString (Cons t) = t
src/Graphics/Gnuplot/Private/LineSpecification.hs view
@@ -1,5 +1,6 @@ module Graphics.Gnuplot.Private.LineSpecification where +import qualified Graphics.Gnuplot.Private.ColorSpecification as Color import Data.Maybe (catMaybes, ) import Graphics.Gnuplot.Utility (quote, ) @@ -14,6 +15,7 @@ { lineStyle_ :: Maybe Int , lineType_ :: Maybe Int , lineWidth_ :: Maybe Double+ , lineColor_ :: Maybe Color.T , pointType_ :: Maybe Int , pointSize_ :: Maybe Double , title_ :: Maybe String@@ -25,6 +27,7 @@ { lineStyle_ = Nothing , lineType_ = Nothing , lineWidth_ = Nothing+ , lineColor_ = Nothing , pointType_ = Nothing , pointSize_ = Nothing , title_ = Nothing@@ -39,6 +42,9 @@ lineWidth :: Double -> T -> T lineWidth x ls = ls{lineWidth_ = Just x} +lineColor :: Color.T -> T -> T+lineColor x ls = ls{lineColor_ = Just x}+ pointType :: Int -> T -> T pointType x ls = ls{pointType_ = Just x} @@ -54,10 +60,11 @@ let showField :: String -> (a -> String) -> (T -> Maybe a) -> Maybe [String] showField s f access = fmap (\a -> [s, f a]) $ access linespec in unwords $ concat $ catMaybes $+ showField "linestyle" show lineStyle_ : showField "linetype" show lineType_ : showField "linewidth" show lineWidth_ :+ showField "linecolor" Color.toString lineColor_ : showField "pointtype" show pointType_ : showField "pointsize" show pointSize_ : showField "title" quote title_ :- showField "linestyle" show lineStyle_ : []
src/Graphics/Gnuplot/Private/Plot.hs view
@@ -1,39 +1,66 @@ module Graphics.Gnuplot.Private.Plot where -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 qualified Graphics.Gnuplot.Private.File as FileClass+import qualified Graphics.Gnuplot.File as File import Graphics.Gnuplot.Utility (quote, commaConcat, ) -import Data.Maybe (mapMaybe, )+import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS+import qualified Control.Monad.Trans.Class as MT+import qualified Data.Accessor.Monad.Trans.State as AccState+import qualified Data.Accessor.Tuple as AccTuple+import qualified Data.Foldable as Fold+import Control.Monad (liftM2, return, )+import Data.Monoid (Monoid, mempty, mappend, )+import Data.Semigroup (Semigroup, (<>), )+import Data.Maybe (Maybe(Just, Nothing), mapMaybe, )+import Data.List (concatMap, map, (++), )+import Data.Function (($), (.), ) +import qualified System.FilePath as Path+import System.FilePath (FilePath, (</>), )++import Prelude (Functor, fmap, String, show, Int, succ, writeFile, )++ {- |-Plots can be assembled using 'mappend' or 'mconcat'.+Plots can be assembled using 'mappend' or 'mconcat'+or several functions from "Data.Foldable". -}-newtype T graph = Cons (State.T Int [File graph])+newtype T graph = Cons (MS.StateT Int (MR.Reader FilePath) [File graph]) +pure :: [File graph] -> T graph+pure = Cons . return++instance Semigroup (T graph) where+ Cons s0 <> Cons s1 = Cons (liftM2 (<>) s0 s1)+ {- Could also be implemented with Control.Monad.Trans.State: mappend = liftA2 mappend -} instance Monoid (T graph) where- mempty = Cons mempty- mappend (Cons s0) (Cons s1) =- Cons (mappend s0 s1)+ mempty = Cons $ return mempty+ mappend = (<>) withUniqueFile :: String -> [graph] -> T graph-withUniqueFile content graphs =- Cons (State.Cons $ \n ->- ([File (tmpFileStem ++ show n ++ ".csv") (Just content) graphs],- succ n))+withUniqueFile content graphs = Cons $ do+ n <- MS.get+ dir <- MT.lift MR.ask+ MS.put $ succ n+ return $+ [File+ (dir </> Path.addExtension (tmpFileStem ++ show n) "csv")+ (Just content) graphs] fromGraphs :: FilePath -> [graph] -> T graph fromGraphs name gs =- Cons (State.pure [File name Nothing gs])+ pure [File name Nothing gs] data File graph =@@ -43,9 +70,9 @@ graphs_ :: [graph] } -writeData :: File graph -> IO ()-writeData (File fn cont _) =- maybe (return ()) (writeFile fn) cont+instance FileClass.C (File graph) where+ write (File fn cont _) =+ Fold.mapM_ (writeFile fn) cont tmpFileStem :: FilePath@@ -63,24 +90,48 @@ fmap (map (\file -> file{graphs_ = map f $ graphs_ file})) mp +{- |+In contrast to the Display.toScript method instantiation+this function leaves the options,+and thus can be used to write the Display.toScript instance for Frame.+-}+toScript :: Graph.C graph => T graph -> Display.Script+toScript p@(Cons mp) =+ Display.Script $ do+ blocks <- AccState.liftT AccTuple.first mp+ let files =+ mapMaybe+ (\blk -> fmap (File.Cons (filename_ blk)) (content_ blk))+ blocks+ graphs =+ concatMap+ (\blk ->+ map+ (\gr ->+ quote (filename_ blk) ++ " " +++ Graph.toString gr) $ graphs_ blk) $+ blocks+ return $+ Display.Body files+ [Graph.commandString (plotCmd p) ++ " " ++ commaConcat graphs]++optionsToScript :: Graph.C graph => OptionSet.T graph -> Display.Script+optionsToScript opts =+ Display.Script $+ AccState.liftT AccTuple.second $ do+ opts0 <- MS.get+ let opts1 = OptionSet.decons opts+ MS.put opts1+ return $+ Display.Body [] $+ OptionSet.diffToString opts0 opts1++defltOpts :: Graph.C graph => T graph -> OptionSet.T graph+defltOpts _ = Graph.defltOptions+ instance Graph.C graph => Display.C (T graph) where- toScript p@(Cons mp) =- Display.Script $ State.Cons $- \(n0, opts) ->- let (blocks, n1) = State.run mp n0- files =- mapMaybe- (\blk -> fmap (Display.File (filename_ blk)) (content_ blk))- blocks- graphs =- concatMap (\blk ->- map (\gr -> quote (filename_ blk) ++ " " ++ Graph.toString gr) $ graphs_ blk) $- blocks- in (Display.Body files- [plotCmd p undefined ++ " " ++ commaConcat graphs],- (n1, opts))+ toScript plot =+ optionsToScript (defltOpts plot) `mappend` toScript plot -plotCmd ::- Graph.C graph =>- T graph -> graph -> String+plotCmd :: Graph.C graph => T graph -> Graph.Command graph plotCmd _plot = Graph.command
+ src/Graphics/Gnuplot/Private/Terminal.hs view
@@ -0,0 +1,19 @@+module Graphics.Gnuplot.Private.Terminal where++data T =+ Cons {+ precommands :: [String],+ options :: [String],+ commands :: [String],+ interactive :: Bool+ }++class C terminal where+ canonical :: terminal -> T++format :: T -> [String]+format (Cons pre opts cmds _ia) =+ pre +++ if null opts+ then cmds+ else (unwords $ "set" : "terminal" : opts) : cmds
src/Graphics/Gnuplot/Simple.hs view
@@ -5,6 +5,10 @@ instead we provide an advanced modularized interface in "Graphics.Gnuplot.Advanced". +Here is a pretty simple example:++> Graphics.Gnuplot.Simple> plotFunc [] (linearScale 1000 (-10,10::Double)) sin+ This was formerly part of the htam package. -} module Graphics.Gnuplot.Simple (@@ -51,27 +55,34 @@ import qualified Graphics.Gnuplot.Plot.ThreeDimensional as Plot3D import qualified Graphics.Gnuplot.Private.LineSpecification as LineSpec import qualified Graphics.Gnuplot.Private.Graph2D as Graph2D-import qualified Graphics.Gnuplot.Private.Graph3D as Graph3D-import qualified Graphics.Gnuplot.Private.GraphType as GraphType+import qualified Graphics.Gnuplot.Private.Graph2DType as GraphType+import qualified Graphics.Gnuplot.Private.Graph as Graph import qualified Graphics.Gnuplot.Private.Plot as Plot +import qualified Graphics.Gnuplot.Value.Tuple as Tuple+import qualified Graphics.Gnuplot.Value.Atom as Atom+ {- import qualified Graphics.Gnuplot.Terminal.PostScript as PS import qualified Graphics.Gnuplot.Terminal.PNG as PNG import qualified Graphics.Gnuplot.Terminal.SVG as SVG -} -import qualified Graphics.Gnuplot.Terminal as Terminal-import qualified Graphics.Gnuplot.Execute as Exec+import qualified Graphics.Gnuplot.Private.Terminal as Terminal -import System.Cmd (rawSystem, ) import Graphics.Gnuplot.Utility- (quote, commaConcat, showTriplet, linearScale, )-import qualified Data.Monoid.State as State+ (quote, commaConcat, semiColonConcat, showTriplet, linearScale, )++import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS++import qualified Graphics.Gnuplot.Private.Command as Cmd+import System.Process (rawSystem, )+import Control.Functor.HT (void, )++import qualified Data.List.Reverse.StrictElement as ListRev+import Data.Foldable (foldMap, ) import Data.Maybe (listToMaybe, mapMaybe, isNothing, )-import Data.List.HT (dropWhileRev, )-import Data.List (intersperse, )-import Data.Monoid (mconcat, ) -- * User front-end@@ -93,6 +104,7 @@ | Title String | XLabel String | YLabel String+ | ZLabel String | XRange (Double, Double) | YRange (Double, Double) | ZRange (Double, Double)@@ -109,8 +121,23 @@ Ratio Double | NoRatio -{- The Int types would be better enumerations- but their interpretations depend on the gnuplot output type. :-( -}+{- |+Be careful with 'LineTitle'+which can only be used as part of gnuplot's @plot@ command+but not as part of @set@.+That is,++> plotList [LineStyle 0 [LineTitle "foobar"]] [0,5..100::Double]++will leave you with an invalid gnuplot script, whereas++> plotListStyle [] (defaultStyle {lineSpec = CustomStyle [LineTitle "foobar"]}) [0,5..100::Double]++does what you want.++The 'Int' types would be better enumerations+but their interpretations depend on the gnuplot output type. :-(+-} data LineAttr = LineType Int | LineWidth Double@@ -163,75 +190,109 @@ -- * plot functions +list :: (Tuple.C a) => [a] -> Plot2D.T Double Double+list = Plot2D.list (GraphType.Cons "lines")+-- list = Plot2D.list GraphType.listLines+ {- | > plotList [] (take 30 (let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs)) -}-plotList :: Show a => [Attribute] -> [a] -> IO ()+plotList ::+ (Tuple.C a) =>+ [Attribute] -> [a] -> IO () plotList attrs =- plot2d attrs . Plot2D.list+ plot2d attrs . list -plotListStyle :: Show a => [Attribute] -> PlotStyle -> [a] -> IO ()+{- |+> plotListStyle [] (defaultStyle{plotType = CandleSticks}) (Plot2D.functionToGraph (linearScale 32 (0,2*pi::Double)) (\t -> (-sin t, -2*sin t, 2*sin t, sin t)))+-}+plotListStyle ::+ (Tuple.C a) =>+ [Attribute] -> PlotStyle -> [a] -> IO () plotListStyle attrs style =- plot2d attrs . setPlotStyle style . Plot2D.list+ plot2d attrs . setPlotStyle style . list -plotLists :: Show a => [Attribute] -> [[a]] -> IO ()+plotLists ::+ (Tuple.C a) =>+ [Attribute] -> [[a]] -> IO () plotLists attrs xss =- plot2d attrs (mconcat $ map Plot2D.list xss)+ plot2d attrs (foldMap list xss) -plotListsStyle :: Show a => [Attribute] -> [(PlotStyle, [a])] -> IO ()+plotListsStyle ::+ (Tuple.C a) =>+ [Attribute] -> [(PlotStyle, [a])] -> IO () plotListsStyle attrs =- plot2d attrs . mconcat .- map (\(style,xs) -> setPlotStyle style $ Plot2D.list xs)+ plot2d attrs .+ foldMap (\(style,xs) -> setPlotStyle style $ list xs) {- | > plotFunc [] (linearScale 1000 (-10,10)) sin -}-plotFunc :: Show a => [Attribute] -> [a] -> (a -> a) -> IO ()+plotFunc ::+ (Atom.C a, Tuple.C a) =>+ [Attribute] -> [a] -> (a -> a) -> IO () plotFunc attrs args f =- plot2d attrs (Plot2D.function args f)+ plot2d attrs (Plot2D.function GraphType.lines args f) {- | > plotFuncs [] (linearScale 1000 (-10,10)) [sin, cos] -}-plotFuncs :: Show a => [Attribute] -> [a] -> [a -> a] -> IO ()+plotFuncs ::+ (Atom.C a, Tuple.C a) =>+ [Attribute] -> [a] -> [a -> a] -> IO () plotFuncs attrs args fs =- plot2d attrs (Plot2D.functions args fs)+ plot2d attrs (Plot2D.functions GraphType.lines args fs) -plotPath :: Show a => [Attribute] -> [(a,a)] -> IO ()+plotPath ::+ (Tuple.C a) =>+ [Attribute] -> [(a,a)] -> IO () plotPath attrs =- plot2d attrs . Plot2D.path+ plot2d attrs . list -plotPaths :: Show a => [Attribute] -> [[(a,a)]] -> IO ()+plotPaths ::+ (Tuple.C a) =>+ [Attribute] -> [[(a,a)]] -> IO () plotPaths attrs xss =- plot2d attrs (mconcat $ map Plot2D.path xss)+ plot2d attrs (foldMap list xss) -plotPathStyle :: Show a => [Attribute] -> PlotStyle -> [(a,a)] -> IO ()+plotPathStyle ::+ (Tuple.C a) =>+ [Attribute] -> PlotStyle -> [(a,a)] -> IO () plotPathStyle attrs style =- plot2d attrs . setPlotStyle style . Plot2D.path+ plot2d attrs . setPlotStyle style . list -plotPathsStyle :: Show a => [Attribute] -> [(PlotStyle, [(a,a)])] -> IO ()+plotPathsStyle ::+ (Tuple.C a) =>+ [Attribute] -> [(PlotStyle, [(a,a)])] -> IO () plotPathsStyle attrs =- plot2d attrs . mconcat .- map (\(style,xs) -> setPlotStyle style $ Plot2D.path xs)+ plot2d attrs .+ foldMap (\(style,xs) -> setPlotStyle style $ list xs) {- | > plotParamFunc [] (linearScale 1000 (0,2*pi)) (\t -> (sin (2*t), cos t)) -}-plotParamFunc :: Show a => [Attribute] -> [a] -> (a -> (a,a)) -> IO ()+plotParamFunc ::+ (Atom.C a, Tuple.C a) =>+ [Attribute] -> [a] -> (a -> (a,a)) -> IO () plotParamFunc attrs args f =- plot2d attrs (Plot2D.parameterFunction args f)+ plot2d attrs (Plot2D.parameterFunction GraphType.lines args f) {- | > plotParamFuncs [] (linearScale 1000 (0,2*pi)) [\t -> (sin (2*t), cos t), \t -> (cos t, sin (2*t))] -}-plotParamFuncs :: Show a => [Attribute] -> [a] -> [a -> (a,a)] -> IO ()+plotParamFuncs ::+ (Atom.C a, Tuple.C a) =>+ [Attribute] -> [a] -> [a -> (a,a)] -> IO () plotParamFuncs attrs args fs =- plot2d attrs (mconcat $ map (Plot2D.parameterFunction args) fs)+ plot2d attrs $+ foldMap (Plot2D.parameterFunction GraphType.lines args) fs -plotDots :: Show a => [Attribute] -> [(a,a)] -> IO ()+plotDots ::+ (Atom.C a, Tuple.C a) =>+ [Attribute] -> [(a,a)] -> IO () plotDots attrs xs =- plot2d attrs (fmap (Graph2D.typ GraphType.dots) $ Plot2D.path xs)+ plot2d attrs (Plot2D.list GraphType.dots xs) @@ -255,19 +316,25 @@ {- | > let xs = [-2,-1.8..2::Double] in plotMesh3d [] [] (do x <- xs; return (do y <- xs; return (x,y,cos(x*x+y*y))))++> let phis = linearScale 30 (-pi, pi :: Double) in plotMesh3d [] [] (do phi <- phis; return (do psi <- phis; let r = 5 + sin psi in return (r * cos phi, r * sin phi, cos psi))) -}-plotMesh3d :: (Show a, Show b, Show c) =>- [Attribute] -> [Attribute3d] -> [[(a,b,c)]] -> IO ()+plotMesh3d ::+ (Atom.C x, Atom.C y, Atom.C z,+ Tuple.C x, Tuple.C y, Tuple.C z) =>+ [Attribute] -> [Attribute3d] -> [[(x,y,z)]] -> IO () plotMesh3d attrs pt dat = plot3d attrs pt (Plot3D.mesh dat) {- | > let xs = [-2,-1.8..2::Double] in plotFunc3d [] [] xs xs (\x y -> exp(-(x*x+y*y))) -}-plotFunc3d :: (Show a, Show b, Show c) =>- [Attribute] -> [Attribute3d] -> [b] -> [c] -> (b -> c -> a) -> IO ()+plotFunc3d ::+ (Atom.C x, Atom.C y, Atom.C z,+ Tuple.C x, Tuple.C y, Tuple.C z) =>+ [Attribute] -> [Attribute3d] -> [x] -> [y] -> (x -> y -> z) -> IO () plotFunc3d attrs pt xArgs yArgs f =- plot3d attrs pt (Plot3D.function xArgs yArgs f)+ plot3d attrs pt (Plot3D.surface xArgs yArgs f) @@ -281,8 +348,7 @@ -> IO () epspdfPlot filename plot = do plot (EPS (filename++".eps") : Key Nothing : [])- rawSystem "epstopdf" [filename++".eps"]- return ()+ void $ rawSystem "epstopdf" [filename++".eps"] {-| Creates an EPS and a PDF graphics and returns a string that can be inserted into a LaTeX document@@ -308,10 +374,8 @@ attrToProg (Custom attribute parameters) = "set " ++ attribute ++ " " ++ unwords parameters -attrToProg (Terminal (Terminal.Cons options commands)) =- concat $- intersperse "; " $- ("set terminal " ++ unwords options) : commands+attrToProg (Terminal term) =+ semiColonConcat $ Terminal.format term attrToProg (EPS filename) = "set terminal postscript eps; " ++ -- latex@@ -343,6 +407,7 @@ attrToProg (Title title_) = "set title " ++ quote title_ attrToProg (XLabel label) = "set xlabel " ++ quote label attrToProg (YLabel label) = "set ylabel " ++ quote label+attrToProg (ZLabel label) = "set zlabel " ++ quote label attrToProg (XRange _) = "" -- xrange is handled in plot command attrToProg (YRange _) = "" -- yrange is handled in plot command attrToProg (ZRange _) = "" -- zrange is handled in plot command@@ -370,37 +435,46 @@ let ranges = map (listToMaybe . flip mapMaybe attrs) [xRangeFromAttr, yRangeFromAttr, zRangeFromAttr] showRng (l,r) = "[" ++ show l ++ ":" ++ show r ++ "]"- in unwords (map (maybe "[:]" showRng) (dropWhileRev isNothing ranges))+ in unwords $ map (maybe "[:]" showRng) (ListRev.dropWhile isNothing ranges) +interactiveTerm :: [Attribute] -> Bool+interactiveTerm =+ all $ \attr ->+ case attr of+ Terminal term -> Terminal.interactive term+ PNG _ -> False+ EPS _ -> False+ _ -> True -plotTypeToGraph :: PlotType -> GraphType.T++plotTypeToGraph :: PlotType -> Graph2D.Type -- GraphType.T plotTypeToGraph t = case t of- Lines -> GraphType.lines- Points -> GraphType.points- LinesPoints -> GraphType.linesPoints- Impulses -> GraphType.impulses- Dots -> GraphType.dots- Steps -> GraphType.steps- FSteps -> GraphType.fSteps- HiSteps -> GraphType.hiSteps- ErrorBars -> GraphType.errorBars- XErrorBars -> GraphType.xErrorBars- YErrorBars -> GraphType.yErrorBars- XYErrorBars -> GraphType.xyErrorBars- ErrorLines -> GraphType.errorLines- XErrorLines -> GraphType.xErrorLines- YErrorLines -> GraphType.yErrorLines- XYErrorLines -> GraphType.xyErrorLines- Boxes -> GraphType.boxes- FilledCurves -> GraphType.filledCurves- BoxErrorBars -> GraphType.boxErrorBars- BoxXYErrorBars -> GraphType.boxXYErrorBars- FinanceBars -> GraphType.financeBars- CandleSticks -> GraphType.candleSticks- Vectors -> GraphType.vectors- PM3d -> GraphType.pm3d+ Lines -> "lines"+ Points -> "points"+ LinesPoints -> "linespoints"+ Impulses -> "impulses"+ Dots -> "dots"+ Steps -> "steps"+ FSteps -> "fsteps"+ HiSteps -> "histeps"+ ErrorBars -> "errorbars"+ XErrorBars -> "xerrorbars"+ YErrorBars -> "yerrorbars"+ XYErrorBars -> "xyerrorbars"+ ErrorLines -> "errorlines"+ XErrorLines -> "xerrorlines"+ YErrorLines -> "yerrorlines"+ XYErrorLines -> "xyerrorlines"+ Boxes -> "boxes"+ FilledCurves -> "filledcurves"+ BoxErrorBars -> "boxerrorbars"+ BoxXYErrorBars -> "boxxyerrorbars"+ FinanceBars -> "financebars"+ CandleSticks -> "candlesticks"+ Vectors -> "vectors"+ PM3d -> "pm3d" plot3dTypeToString :: Plot3dType -> String@@ -423,30 +497,24 @@ -plot2d :: [Attribute] -> Plot2D.T -> IO ()-plot2d attrs (Plot.Cons mp) =- let files = State.evaluate 0 mp- in do mapM_ Plot.writeData files- callGnuplot attrs "plot" $- concatMap (\(Plot.File filename _ grs) ->- map (\gr -> quote filename ++ " " ++ Graph2D.toString gr) grs) $- files+plot2d ::+ (Atom.C x, Atom.C y) =>+ [Attribute] -> Plot2D.T x y -> IO ()+plot2d attrs plt =+ runGnuplot attrs "plot" plt -setPlotStyle :: PlotStyle -> Plot2D.T -> Plot2D.T+setPlotStyle :: PlotStyle -> Plot2D.T x y -> Plot2D.T x y setPlotStyle ps = fmap (Graph2D.typ (plotTypeToGraph $ plotType ps) . Graph2D.lineSpec (lineSpecRecord $ lineSpec ps)) -plot3d :: [Attribute] -> [Attribute3d] -> Plot3D.T -> IO ()-plot3d attrs pt (Plot.Cons mp) =- let files = State.evaluate 0 mp- in do mapM_ Plot.writeData files- callGnuplot- (attrs ++ [Custom "pm3d" (map attribute3dToString pt)]) "splot" $- concatMap (\(Plot.File filename _ grs) ->- map (\gr -> quote filename ++ " " ++ Graph3D.toString gr) grs) $- files+plot3d ::+ (Atom.C x, Atom.C y, Atom.C z) =>+ [Attribute] -> [Attribute3d] -> Plot3D.T x y z -> IO ()+plot3d attrs pt plt =+ runGnuplot+ (Custom "pm3d" (map attribute3dToString pt) : attrs) "splot" plt lineSpecRecord :: LineSpec -> LineSpec.T@@ -466,13 +534,21 @@ LineTitle s -> LineSpec.title s ) -callGnuplot :: [Attribute] -> String -> [String] -> IO ()-callGnuplot attrs cmd params =- Exec.simple- (map attrToProg attrs ++- [cmd ++ " " ++- extractRanges attrs ++ " " ++- commaConcat params])- ["-persist"]- -- instead of the option, one can also use 'set terminal x11 persist'- >> return ()+runGnuplot ::+ Graph.C graph =>+ [Attribute] -> String -> Plot.T graph -> IO ()+runGnuplot attrs cmd (Plot.Cons mp) =+ void $ Cmd.asyncIfInteractive (interactiveTerm attrs) $ Cmd.run $ \dir ->+ let files = MR.runReader (MS.evalStateT mp 0) dir+ in (map attrToProg attrs +++ [cmd ++ " " +++ extractRanges attrs ++ " " +++ commaConcat (plotFileStatements files)],+ files)++plotFileStatements ::+ Graph.C graph => [Plot.File graph] -> [String]+plotFileStatements =+ concatMap+ (\(Plot.File filename _ grs) ->+ map (\gr -> quote filename ++ " " ++ Graph.toString gr) grs)
src/Graphics/Gnuplot/Terminal.hs view
@@ -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
+ src/Graphics/Gnuplot/Terminal/Default.hs view
@@ -0,0 +1,21 @@+module Graphics.Gnuplot.Terminal.Default (+ T, cons,+ ) where++import qualified Graphics.Gnuplot.Private.Terminal as Terminal+++data T = Cons++cons :: T+cons = Cons+++instance Terminal.C T where+ canonical _term =+ Terminal.Cons {+ Terminal.precommands = [],+ Terminal.options = [],+ Terminal.commands = [],+ Terminal.interactive = True -- Always true? I don't know.+ }
src/Graphics/Gnuplot/Terminal/PNG.hs view
@@ -1,20 +1,22 @@ module Graphics.Gnuplot.Terminal.PNG ( T, cons,+ encoding, transparent, noTransparent, interlace, noInterlace, trueColor, noTrueColor, 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 qualified Graphics.Gnuplot.Private.Encoding as Encoding import Data.Maybe (catMaybes, )-import Graphics.Gnuplot.Utility (quote, )+import Graphics.Gnuplot.Utility (quote, formatBool, ) data T = Cons { filename_ :: FilePath,+ encoding_ :: Maybe Encoding.T, transparent_ :: Maybe Bool, interlace_ :: Maybe Bool, trueColor_ :: Maybe Bool,@@ -25,6 +27,7 @@ cons path = Cons { filename_ = path,+ encoding_ = Nothing, transparent_ = Nothing, interlace_ = Nothing, trueColor_ = Nothing,@@ -32,6 +35,13 @@ } +{- |+Setting the encoding to anything different+from 'Graphics.Gnuplot.Encoding.locale'+makes only sense if you write your gnuplot files manually using this encoding.+-}+encoding :: Encoding.T -> T -> T+encoding enc term = term{encoding_ = Just enc} transparent, noTransparent :: T -> T transparent term = term{transparent_ = Just True}@@ -78,6 +88,7 @@ instance Terminal.C T where canonical term = Terminal.Cons {+ Terminal.precommands = Encoding.formatMaybe $ encoding_ term, Terminal.options = "png" : catMaybes (@@ -87,5 +98,6 @@ (fmap formatFontSize $ fontSize_ term) : []), Terminal.commands =- ["set output " ++ (quote $ filename_ term)]+ ["set output " ++ (quote $ filename_ term)],+ Terminal.interactive = False }
src/Graphics/Gnuplot/Terminal/PostScript.hs view
@@ -1,30 +1,47 @@ module Graphics.Gnuplot.Terminal.PostScript ( T, cons,+ encoding, landscape, portrait, eps, color, monochrome,+ font, embedFont, ) where -import qualified Graphics.Gnuplot.Terminal as Terminal-import Data.Maybe (catMaybes, )-import Graphics.Gnuplot.Utility (quote, )+import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import qualified Graphics.Gnuplot.Private.Encoding as Encoding+import Graphics.Gnuplot.Utility (listFromMaybeWith, quote, )+import Data.Foldable (foldMap, ) data T = Cons { filename_ :: FilePath,+ encoding_ :: Maybe Encoding.T, mode_ :: Maybe Mode,- color_ :: Maybe Bool+ color_ :: Maybe Bool,+ embedFont_ :: [FilePath],+ font_ :: Maybe (String, Int) } cons :: FilePath -> T cons path = Cons { filename_ = path,+ encoding_ = Nothing, mode_ = Nothing,- color_ = Nothing+ color_ = Nothing,+ embedFont_ = [],+ font_ = Nothing } +{- |+Setting the encoding to anything different+from 'Graphics.Gnuplot.Encoding.locale'+makes only sense if you write your gnuplot files manually using this encoding.+-}+encoding :: Encoding.T -> T -> T+encoding enc term = term{encoding_ = Just enc}+ landscape :: T -> T landscape = setMode Landscape @@ -43,7 +60,20 @@ monochrome term = term{color_ = Just False} +font :: String -> Int -> T -> T+font fontName fontSize term =+ term{font_ = Just (fontName, fontSize)} +{- |+Embed a font file in the generated PostScript output.+Each call adds a new font file,+there is no way to remove it again.+-}+embedFont :: FilePath -> T -> T+embedFont fontFile term =+ term{embedFont_ = fontFile : embedFont_ term}++ -- private functions data Mode =@@ -65,12 +95,15 @@ instance Terminal.C T where canonical term = Terminal.Cons {+ Terminal.precommands = Encoding.formatMaybe $ encoding_ term, Terminal.options = "postscript" :- catMaybes (- (fmap formatMode $ mode_ term) :- (fmap (\b -> if b then "color" else "monochrome") $ color_ term) :- []),+ (listFromMaybeWith formatMode $ mode_ term) +++ (listFromMaybeWith (\b -> if b then "color" else "monochrome") $ color_ term) +++ (concatMap (\path -> "fontfile" : quote path : []) $ embedFont_ term) +++ (foldMap (\(name,size) -> "font" : quote name : show size : []) $ font_ term) +++ [], Terminal.commands =- ["set output " ++ (quote $ filename_ term)]+ ["set output " ++ (quote $ filename_ term)],+ Terminal.interactive = False }
+ src/Graphics/Gnuplot/Terminal/QT.hs view
@@ -0,0 +1,53 @@+{- |+Terminal using QT.+Derived from wxt.+-}+module Graphics.Gnuplot.Terminal.QT (+ T, cons,+ title, noTitle,+ persist, noPersist,+ ) where++import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import Data.Maybe (catMaybes, )+import Graphics.Gnuplot.Utility (quote, formatBool, )+++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.precommands = [],+ Terminal.options =+ "qt" :+ catMaybes (+ (fmap quote $ title_ term) :+ (fmap (formatBool "persist") $ persist_ term) :+ []),+ Terminal.commands = [],+ Terminal.interactive = True+ }
src/Graphics/Gnuplot/Terminal/SVG.hs view
@@ -1,22 +1,33 @@ module Graphics.Gnuplot.Terminal.SVG ( T, cons,+ encoding, ) where -import qualified Graphics.Gnuplot.Terminal as Terminal+import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import qualified Graphics.Gnuplot.Private.Encoding as Encoding import Graphics.Gnuplot.Utility (quote, ) data T = Cons {- filename_ :: FilePath+ filename_ :: FilePath,+ encoding_ :: Maybe Encoding.T } cons :: FilePath -> T cons path = Cons {- filename_ = path+ filename_ = path,+ encoding_ = Nothing } +{- |+Setting the encoding to anything different+from 'Graphics.Gnuplot.Encoding.locale'+makes only sense if you write your gnuplot files manually using this encoding.+-}+encoding :: Encoding.T -> T -> T+encoding enc term = term{encoding_ = Just enc} -- private functions@@ -24,9 +35,11 @@ instance Terminal.C T where canonical term = Terminal.Cons {+ Terminal.precommands = Encoding.formatMaybe $ encoding_ term, Terminal.options = "svg" : [], Terminal.commands =- ["set output " ++ (quote $ filename_ term)]+ ["set output " ++ (quote $ filename_ term)],+ Terminal.interactive = False }
+ src/Graphics/Gnuplot/Terminal/WXT.hs view
@@ -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 Data.Maybe (catMaybes, )+import Graphics.Gnuplot.Utility (quote, formatBool, )+++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.precommands = [],+ Terminal.options =+ "wxt" :+ catMaybes (+ (fmap quote $ title_ term) :+ (fmap (formatBool "persist") $ persist_ term) :+ []),+ Terminal.commands = [],+ Terminal.interactive = True+ }
src/Graphics/Gnuplot/Terminal/X11.hs view
@@ -4,10 +4,9 @@ persist, noPersist, ) where -import qualified Graphics.Gnuplot.Terminal as Terminal-import Graphics.Gnuplot.Terminal (formatBool, )+import qualified Graphics.Gnuplot.Private.Terminal as Terminal import Data.Maybe (catMaybes, )-import Graphics.Gnuplot.Utility (quote, )+import Graphics.Gnuplot.Utility (quote, formatBool, ) data T =@@ -38,12 +37,13 @@ instance Terminal.C T where canonical term = Terminal.Cons {+ Terminal.precommands = [], Terminal.options = "x11" : catMaybes ( (fmap quote $ title_ term) : (fmap (formatBool "persist") $ persist_ term) : []),- Terminal.commands =- []+ Terminal.commands = [],+ Terminal.interactive = True }
src/Graphics/Gnuplot/Time.hs view
@@ -1,7 +1,6 @@ module Graphics.Gnuplot.Time where -import System.Locale (defaultTimeLocale, )-import Data.Time.Format (FormatTime, formatTime, )+import Data.Time.Format (FormatTime, formatTime, defaultTimeLocale, ) import Data.Tuple.HT (mapFst, ) {- |
src/Graphics/Gnuplot/Utility.hs view
@@ -1,9 +1,12 @@ module Graphics.Gnuplot.Utility where +import Text.Printf (printf, )++import qualified Data.Char as Char import Data.List (intersperse, ) -functionToGraph :: [a] -> (a -> a) -> [(a,a)]+functionToGraph :: [x] -> (x -> y) -> [(x,y)] functionToGraph args f = map (\x -> (x, f x)) args -- functionToGraph args f = map swap $ attachKey f args @@ -22,5 +25,40 @@ semiColonConcat = concat . intersperse "; " -quote :: String -> String-quote = show+{-+In former versions this was simply 'show'.+However, Haskell formats non-ASCII characters with decimal backslash sequences+whereas gnuplot expects octal ones.+gnuplot does also not accept bigger octal numbers.+The current version writes non-ASCII printable characters+with the system default encoding.+-}+quote, _quote :: String -> String+quote str = '"' : foldr (++) "\"" (map escapeChar str)+_quote str = '"' : concatMap escapeChar str ++ "\""++escapeChar :: Char -> String+escapeChar c =+ case c of+ '"' -> "\\\""+ '\\' -> "\\\\"+ '\t' -> "\\t"+ '\n' -> "\\n"+ _ -> if Char.isPrint c then [c] else printf "\\%o" $ Char.ord c++assembleCells :: [[ShowS]] -> String+assembleCells ps =+ foldr ($) ""+ (concatMap+ (\p ->+ intersperse (showString ", ") p +++ [showString "\n"])+ ps)+++listFromMaybeWith :: (a -> b) -> Maybe a -> [b]+listFromMaybeWith f = maybe [] ((:[]) . f)++formatBool :: String -> Bool -> String+formatBool name b =+ if b then name else "no"++name
+ src/Graphics/Gnuplot/Value/Atom.hs view
@@ -0,0 +1,54 @@+{- |+Provide a class that restricts the range of Haskell types+to the ones that gnuplot can process.+-}+module Graphics.Gnuplot.Value.Atom (+ OptionSet(..),+ C(..),+ ) where++import qualified Graphics.Gnuplot.Private.FrameOption as Option+import Graphics.Gnuplot.Utility (quote, )++import qualified Data.Time as Time+import Data.Word (Word8, Word16, Word32, Word64, )+import Data.Int (Int8, Int16, Int32, Int64, )+import Data.Ratio (Ratio, )+++data OptionSet a =+ OptionSet {+ optData :: [String],+ optFormat :: [String],+ optOthers :: [(Option.T, [String])]+ }++class C a where+ options :: OptionSet a+ options =+ OptionSet [] [{- quote "%g" -}] []++instance C Float where+instance C Double where+instance C Int where+instance C Integer where+instance (Integral a) => C (Ratio a) where++instance C Int8 where+instance C Int16 where+instance C Int32 where+instance C Int64 where+instance C Word8 where+instance C Word16 where+instance C Word32 where+instance C Word64 where+++timeOptions :: OptionSet time+timeOptions =+ OptionSet ["time"] [quote "%d/%m"] [(Option.timeFmt, [quote "%s"])]++instance C Time.Day where+ options = timeOptions+instance C Time.UTCTime where+ options = timeOptions
+ src/Graphics/Gnuplot/Value/ColumnSet.hs view
@@ -0,0 +1,38 @@+{- |+We provide a way to specify a set of columns+that matches the tuple structure of a certain graph type.+-}+module Graphics.Gnuplot.Value.ColumnSet+ (T(Cons), atom, pair, triple, quadruple,+ ) where++import qualified Graphics.Gnuplot.Value.Atom as Atom+++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]++pair :: T a -> T b -> T (a,b)+pair (Cons ai) (Cons bi) = Cons (ai++bi)++triple :: T a -> T b -> T c -> T (a,b,c)+triple (Cons ai) (Cons bi) (Cons ci) = Cons (ai++bi++ci)++quadruple :: T a -> T b -> T c -> T d -> T (a,b,c,d)+quadruple (Cons ai) (Cons bi) (Cons ci) (Cons di) = Cons (ai++bi++ci++di)
+ src/Graphics/Gnuplot/Value/Tuple.hs view
@@ -0,0 +1,118 @@+{- |+Provide a class that renders multiple Haskell values in a text form+that is accessible by gnuplot.++Maybe we add a method for the binary interface to gnuplot later.+-}+module Graphics.Gnuplot.Value.Tuple (+ C(text, columnCount),+ ColumnCount(ColumnCount),+ Label(Label),+ ) where++import Graphics.Gnuplot.Utility (quote)++import Data.Time.Format (defaultTimeLocale, )+import qualified Data.Time as Time++import Data.Word (Word8, Word16, Word32, Word64, )+import Data.Int (Int8, Int16, Int32, Int64, )+import Data.Ratio (Ratio, )++import Data.Function (id, ($), (.), )+import Text.Show (Show, ShowS, shows, showString, )+import Prelude+ (Eq, Ord, String, Int, Integer, Integral, Float, Double,+ realToFrac, (+), (++), )+++class C a where+ {- |+ For values that are also in Atom class,+ 'text' must generate a singleton list.+ -}+ text :: a -> [ShowS]++ {- |+ It must hold @ColumnCount (length (text x)) == columnCount@.+ -}+ 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 = (:[])+++instance C Float where text = singleton . shows+instance C Double where text = singleton . shows+instance C Int where text = singleton . shows+instance C Integer where text = singleton . shows+instance (Integral a) => C (Ratio a) where+ text = singleton . shows . (id :: Double->Double) . realToFrac++instance C Int8 where text = singleton . shows+instance C Int16 where text = singleton . shows+instance C Int32 where text = singleton . shows+instance C Int64 where text = singleton . shows+instance C Word8 where text = singleton . shows+instance C Word16 where text = singleton . shows+instance C Word32 where text = singleton . shows+instance C Word64 where text = singleton . shows++instance C Time.Day where+ text d = text $ Time.UTCTime d 0+instance C Time.UTCTime where+ text = singleton . showString . Time.formatTime defaultTimeLocale "%s"++newtype Label = Label String+instance C Label where text (Label str) = singleton $ showString $ quote str+++instance (C a, C b) => C (a,b) where+ text (a,b) = text a ++ text 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+ 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+ columnCount =+ pure (,,,)+ <*> columnCount+ <*> columnCount+ <*> columnCount+ <*> columnCount