gnuplot 0.5.1 → 0.5.2
raw patch · 34 files changed
+505/−172 lines, 34 filesdep +data-accessordep +data-accessor-transformersdep +deepseqdep −monoid-transformerdep ~utility-ht
Dependencies added: data-accessor, data-accessor-transformers, deepseq, temporary, transformers
Dependencies removed: monoid-transformer
Dependency ranges changed: utility-ht
Files
- Makefile +17/−4
- execute/pipe/Graphics/Gnuplot/Execute.hs +3/−1
- execute/shell/Graphics/Gnuplot/Execute.hs +4/−3
- execute/tmp/Graphics/Gnuplot/Execute.hs +14/−4
- gnuplot.cabal +25/−6
- os/generic/Graphics/Gnuplot/Private/OS.hs +4/−0
- os/windows/Graphics/Gnuplot/Private/OS.hs +4/−0
- src/Demo.hs +45/−13
- src/Graphics/Gnuplot/Advanced.hs +72/−28
- src/Graphics/Gnuplot/File.hs +17/−0
- src/Graphics/Gnuplot/Frame/Option.hs +4/−0
- src/Graphics/Gnuplot/Frame/OptionSet.hs +32/−11
- src/Graphics/Gnuplot/Frame/OptionSet/Style.hs +3/−5
- src/Graphics/Gnuplot/Graph/ThreeDimensional.hs +5/−2
- src/Graphics/Gnuplot/Graph/TwoDimensional.hs +5/−0
- src/Graphics/Gnuplot/Plot.hs +3/−0
- src/Graphics/Gnuplot/Plot/ThreeDimensional.hs +3/−5
- src/Graphics/Gnuplot/Private/Command.hs +28/−0
- src/Graphics/Gnuplot/Private/Display.hs +9/−16
- src/Graphics/Gnuplot/Private/File.hs +4/−0
- src/Graphics/Gnuplot/Private/FrameOption.hs +29/−4
- src/Graphics/Gnuplot/Private/FrameOptionSet.hs +34/−3
- src/Graphics/Gnuplot/Private/Graph2DType.hs +10/−0
- src/Graphics/Gnuplot/Private/Graph3D.hs +3/−0
- src/Graphics/Gnuplot/Private/Graph3DType.hs +9/−0
- src/Graphics/Gnuplot/Private/Plot.hs +50/−33
- src/Graphics/Gnuplot/Private/Terminal.hs +7/−3
- src/Graphics/Gnuplot/Simple.hs +32/−24
- src/Graphics/Gnuplot/Terminal/Default.hs +20/−0
- src/Graphics/Gnuplot/Terminal/PNG.hs +2/−1
- src/Graphics/Gnuplot/Terminal/PostScript.hs +2/−1
- src/Graphics/Gnuplot/Terminal/SVG.hs +2/−1
- src/Graphics/Gnuplot/Terminal/WXT.hs +2/−2
- src/Graphics/Gnuplot/Terminal/X11.hs +2/−2
Makefile view
@@ -1,13 +1,26 @@ ghci: ghci-tmp ghci-tmp:- ghci -Wall -i:src:dist/build/autogen:execute/tmp src/Graphics/Gnuplot/Simple.hs+ ghci -Wall -i:src:dist/build/autogen:os/generic:execute/tmp src/Graphics/Gnuplot/Simple.hs ghci-pipe:- ghci -Wall -i:src:dist/build/autogen:execute/pipe src/Graphics/Gnuplot/Simple.hs+ ghci -Wall -i:src:dist/build/autogen:os/generic:execute/pipe src/Graphics/Gnuplot/Simple.hs ghci-shell:- ghci -Wall -i:src:dist/build/autogen:execute/shell src/Graphics/Gnuplot/Simple.hs+ ghci -Wall -i:src:dist/build/autogen:os/generic:execute/shell src/Graphics/Gnuplot/Simple.hs ghci-demo:- ghci -Wall -i:src:dist/build/autogen:execute/tmp src/Demo.hs+ ghci -Wall -i:src:dist/build/autogen:os/generic: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
execute/pipe/Graphics/Gnuplot/Execute.hs view
@@ -1,5 +1,7 @@ module Graphics.Gnuplot.Execute where +import Graphics.Gnuplot.Private.OS (gnuplotName, )+ import System.Exit (ExitCode, ) import System.IO (hPutStr, ) import qualified System.Process as Proc@@ -12,6 +14,6 @@ simple program options = do -- putStrLn cmd (inp,_out,_err,pid) <-- Proc.runInteractiveProcess "gnuplot" options Nothing Nothing+ Proc.runInteractiveProcess gnuplotName options Nothing Nothing hPutStr inp (unlines program) Proc.waitForProcess pid
execute/shell/Graphics/Gnuplot/Execute.hs view
@@ -1,9 +1,10 @@ module Graphics.Gnuplot.Execute where +import Graphics.Gnuplot.Private.OS (gnuplotName, )+import Graphics.Gnuplot.Utility (quote, semiColonConcat, )+ import System.Exit (ExitCode, ) import System.Cmd (system, )-import Graphics.Gnuplot.Utility- (quote, semiColonConcat, ) simple ::@@ -13,7 +14,7 @@ simple program options = let cmd = "sh -c 'echo " ++ quote (semiColonConcat program) ++- " | gnuplot " ++ unwords options ++ "'"+ " | " ++ gnuplotName ++ " " ++ unwords options ++ "'" in do --putStrLn cmd system cmd
execute/tmp/Graphics/Gnuplot/Execute.hs view
@@ -1,7 +1,11 @@ module Graphics.Gnuplot.Execute where +import Graphics.Gnuplot.Private.OS (gnuplotName, )++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 +16,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 gnuplotName (options ++ [path])+ (exitCode, _out, _err) <-+ readProcessWithExitCode gnuplotName (options ++ [path]) []+ -- putStr out+ -- putStr err+ return exitCode
gnuplot.cabal view
@@ -1,5 +1,5 @@ Name: gnuplot-Version: 0.5.1+Version: 0.5.2 License: BSD3 License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>@@ -33,8 +33,10 @@ you can switch to more convenient but probably less portable ways of feeding gnuplot with a script.+ .+ Alternative packages: @plot@, @HPlot@, @Chart@, @textPlot@, @easyplot@ Tested-With: GHC==6.8.2, GHC==6.12.3-Tested-With: GHC==7.0.2, GHC==7.4.2, GHC==7.6.1+Tested-With: GHC==7.0.2, GHC==7.4.2, GHC==7.6.3 Cabal-Version: >=1.6 Build-Type: Simple Extra-Source-Files:@@ -42,11 +44,13 @@ execute/tmp/Graphics/Gnuplot/Execute.hs execute/pipe/Graphics/Gnuplot/Execute.hs execute/shell/Graphics/Gnuplot/Execute.hs+ os/windows/Graphics/Gnuplot/Private/OS.hs+ os/generic/Graphics/Gnuplot/Private/OS.hs Data-Files: data/runtime.data Source-Repository this- Tag: 0.5.1+ Tag: 0.5.2 Type: darcs Location: http://code.haskell.org/gnuplot/ @@ -75,10 +79,15 @@ Library Build-Depends:+ filepath >=1.1 && <1.4,+ temporary >=1.1 && <1.2, array >=0.1 && <0.5, containers >=0.1 && <0.6,- utility-ht >=0.0.1 && <0.1,- monoid-transformer >=0.0.2 && <0.1+ utility-ht >=0.0.8 && <0.1,+ data-accessor-transformers >=0.2.1 && <0.3,+ data-accessor >=0.2.2 && <0.3,+ transformers >=0.3 && <0.4,+ deepseq >=1.0 && <1.4 If flag(splitBase) Build-Depends: process >=1.0 && <1.2,@@ -99,13 +108,19 @@ Hs-Source-Dirs: execute/shell Else Hs-Source-Dirs: execute/tmp+ If os(windows)+ Hs-Source-Dirs: os/windows+ Else+ Hs-Source-Dirs: os/generic Exposed-Modules: 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@@ -116,6 +131,7 @@ 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@@ -142,6 +158,9 @@ Graphics.Gnuplot.Private.GraphEmpty Graphics.Gnuplot.Private.Terminal Graphics.Gnuplot.Private.Display+ Graphics.Gnuplot.Private.File+ Graphics.Gnuplot.Private.Command+ Graphics.Gnuplot.Private.OS Graphics.Gnuplot.Utility Graphics.Gnuplot.Execute @@ -151,5 +170,5 @@ Else Buildable: False GHC-Options: -Wall- Hs-Source-Dirs: src, execute/tmp+ Hs-Source-Dirs: src, execute/tmp, os/generic Main-Is: Demo.hs
+ os/generic/Graphics/Gnuplot/Private/OS.hs view
@@ -0,0 +1,4 @@+module Graphics.Gnuplot.Private.OS where++gnuplotName :: String+gnuplotName = "gnuplot"
+ os/windows/Graphics/Gnuplot/Private/OS.hs view
@@ -0,0 +1,4 @@+module Graphics.Gnuplot.Private.OS where++gnuplotName :: String+gnuplotName = "pgnuplot"
src/Demo.hs view
@@ -25,9 +25,10 @@ import qualified Paths_gnuplot as Path import System.FilePath ((</>), ) +import Control.Monad (liftM2, ) import Data.Array (listArray, ) import Data.Foldable (foldMap, )-import Data.Monoid (mappend, )+import Data.Monoid (mappend, mconcat, ) simple2d :: Plot2D.T Double Double@@ -43,7 +44,7 @@ list2d :: Plot2D.T Int Integer list2d =- Plot2D.list Graph2D.listPoints [0,1,1,2,3,5,8,13::Integer]+ Plot2D.list Graph2D.listPoints [0,1,1,2,3,5,8,13] candle2d :: Plot2D.T Time.Day Double candle2d =@@ -52,6 +53,13 @@ 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.key False $ Opts.deflt) $@@ -67,9 +75,9 @@ 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.yRange2d (0,3000) $ Opts.deflt) $ foldMap (\(title,dat) -> fmap (Graph2D.lineSpec (LineSpec.title title LineSpec.deflt)) $@@ -88,17 +96,30 @@ Opts.xRange2d domain $ Opts.yRange2d (-1.5,1.5) $ Opts.deflt- in Frame.cons frameOpts $- foldMap (\(name,f) ->- fmap (Graph2D.lineSpec- (LineSpec.title name $- LineSpec.deflt)) $- Plot2D.function Graph2D.lines (linearScale 100 domain) f) $- ("sin", sin) :- ("cos", cos) :- ("tan", tan) :- []+ in Frame.cons frameOpts $+ foldMap (\(name,f) ->+ fmap (Graph2D.lineSpec+ (LineSpec.title name $+ LineSpec.deflt)) $+ Plot2D.function Graph2D.lines (linearScale 100 domain) f) $+ ("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 =@@ -157,6 +178,14 @@ 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) =@@ -185,13 +214,16 @@ GP.plotDefault simple2d : GP.plotDefault list2d : 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@@ -72,18 +72,26 @@ module Graphics.Gnuplot.Advanced ( plot, plotDefault,+ plotSync,+ plotAsync,+ fileContents, ) where import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet import qualified Graphics.Gnuplot.Private.Display as Display- import qualified Graphics.Gnuplot.Private.Terminal as Terminal-import qualified Graphics.Gnuplot.Execute as Exec+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 qualified Data.Monoid.State as State+import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS import Data.Monoid (Monoid, mempty, )-import Graphics.Gnuplot.Utility (semiColonConcat, )+import Control.Functor.HT (void, )+import Data.Tuple.HT (mapFst, ) -- * User front-end@@ -96,43 +104,79 @@ 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 =- plotCore (formatTerminal term :)+plot term gfx =+ case Terminal.canonical term of+ cterm ->+ Cmd.asyncIfInteractive+ (Terminal.interactive cterm)+ (plotCore cterm gfx) -{- |-Plot using the default gnuplot terminal.--}-plotDefault ::- (Display.C gfx) =>- gfx -> IO ExitCode-plotDefault =- plotCore id+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) =>- ([String] -> [String]) -> gfx -> IO ExitCode+ 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.initial) $+ 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- (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 semiColonConcat $- ("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.
+ 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/Option.hs view
@@ -24,6 +24,10 @@ yTicks, zTicks, + xLogScale,+ yLogScale,+ zLogScale,+ xData, yData, zData,
src/Graphics/Gnuplot/Frame/OptionSet.hs view
@@ -4,10 +4,14 @@ OptionSet.add, OptionSet.remove,+ OptionSet.boolean,+ OptionSet.addBool, size, title, key,+ keyInside,+ keyOutside, xRange2d, yRange2d, xRange3d,@@ -21,6 +25,9 @@ xTicks3d, yTicks3d, zTicks3d,+ xLogScale,+ yLogScale,+ zLogScale, grid, gridXTicks, gridYTicks,@@ -49,7 +56,7 @@ import Graphics.Gnuplot.Private.FrameOptionSet (T, ) -import Graphics.Gnuplot.Utility (quote, formatBool, )+import Graphics.Gnuplot.Utility (quote, ) import qualified Data.List as List @@ -69,6 +76,12 @@ 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@@ -220,26 +233,34 @@ 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 =- gridTicks Option.gridXTicks b .- gridTicks Option.gridYTicks b .- gridTicks Option.gridZTicks 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 = gridTicks Option.gridXTicks+gridXTicks = OptionSet.addBool Option.gridXTicks gridYTicks :: Graph.C graph => Bool -> T graph -> T graph-gridYTicks = gridTicks Option.gridYTicks+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 = gridTicks Option.gridZTicks--gridTicks :: Graph.C graph => Option.T -> Bool -> T graph -> T graph-gridTicks opt@(Option.Cons _ name) b =- OptionSet.add opt [formatBool name b]+gridZTicks = OptionSet.addBool Option.gridZTicks boxwidthRelative ::
src/Graphics/Gnuplot/Frame/OptionSet/Style.hs view
@@ -15,13 +15,11 @@ fillSolid :: Graph.C graph => T graph -> T graph fillSolid =- OptionSet.add Option.styleFillSolid ["solid"]+ OptionSet.addBool Option.styleFillSolid True fillBorder :: Graph.C graph => Bool -> T graph -> T graph-fillBorder on =- if on- then OptionSet.add Option.styleFillBorder ["border"]- else OptionSet.add Option.styleFillBorder ["noborder"]+fillBorder =+ OptionSet.addBool Option.styleFillBorder fillBorderLineType :: Graph.C graph => Int -> T graph -> T graph fillBorderLineType n =
src/Graphics/Gnuplot/Graph/ThreeDimensional.hs view
@@ -8,8 +8,11 @@ impulses, vectors,- pm3d,+ Graph3DType.pm3d,++ Graph3DType.lines,+ points, ) where import Graphics.Gnuplot.Private.Graph3D-import Graphics.Gnuplot.Private.Graph3DType hiding (T, )+import Graphics.Gnuplot.Private.Graph3DType as Graph3DType hiding (T, )
src/Graphics/Gnuplot/Graph/TwoDimensional.hs view
@@ -46,6 +46,11 @@ financeBars, candleSticks, vectors,+ image,++ filledStripe,+ filledStripeAbove,+ filledStripeBelow, ) where import Graphics.Gnuplot.Private.Graph2D
+ 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
@@ -55,11 +55,9 @@ Tuple.C x, Tuple.C y, Tuple.C z) => [[(x,y,z)]] -> T x y z mesh pss =- let typ :: [[a]] -> Type.T x y z a -> Type.T x y z a- typ _ = id- in Plot.withUniqueFile- (assembleCells (concat (map (\ps -> map Tuple.text ps ++ [[]]) pss)))- [Graph.deflt (typ pss Type.pm3d) (1:2:3:[])]+ Plot.withUniqueFile+ (assembleCells (concatMap (\ps -> map Tuple.text ps ++ [[]]) pss))+ [Graph.pm3d] surface :: (Atom.C x, Atom.C y, Atom.C z,
+ 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
@@ -1,47 +1,40 @@ 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 Data.Monoid.State as State+import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS+import Control.Monad (liftM2, ) import Data.Monoid (Monoid, mempty, mappend, ) newtype Script = Script {- runScript :: State.T (Int, OptionSet) Body+ runScript :: MS.StateT (Int, OptionSet) (MR.Reader FilePath) Body } pure :: Body -> Script-pure = Script . State.pure+pure = Script . return data Body = Body {- files :: [File],+ files :: [File.T], 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+ mempty = Script $ return mempty mappend (Script b0) (Script b1) =- Script (mappend b0 b1)+ Script (liftM2 mappend b0 b1) {- Could also be implemented with Control.Monad.Trans.State:
+ 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/FrameOption.hs view
@@ -9,15 +9,35 @@ It is altered with gnuplot's set command. The first field in 'T' is the name of the option and the name of the according internal state in gnuplot.+ Sometimes the addressed state is not explicitly mentioned but is expressed by the syntax of the values.-For this case we manage an identifier in the second field.-It is only used for distinguishing between these states,-but it is never written to a gnuplot script.+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) +{- |+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 @@ -39,7 +59,11 @@ 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" "" @@ -55,7 +79,8 @@ sizeScale :: T; sizeScale = size "scale"-keyShow :: T; keyShow = key "show"+keyShow :: T; keyShow = key "show"+keyPosition :: T; keyPosition = key "position" xRangeBounds :: T; xRangeBounds = xRange "bounds" yRangeBounds :: T; yRangeBounds = yRange "bounds"
src/Graphics/Gnuplot/Private/FrameOptionSet.hs view
@@ -11,7 +11,7 @@ module Graphics.Gnuplot.Private.FrameOptionSet where import qualified Graphics.Gnuplot.Private.FrameOption as Option--- import Graphics.Gnuplot.Utility (quote, )+import Graphics.Gnuplot.Utility (formatBool, ) import qualified Data.Map as Map @@ -67,7 +67,8 @@ [] {- |-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".@@ -77,7 +78,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) =@@ -102,8 +107,34 @@ (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/Graph2DType.hs view
@@ -62,8 +62,13 @@ 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)) + listLines = Cons "lines" listPoints = Cons "points" listLinesPoints = Cons "linespoints"@@ -104,6 +109,11 @@ financeBars = Cons "financebars" candleSticks = Cons "candlesticks" vectors = Cons "vectors"+image = Cons "image"++filledStripe = Cons "filledcurves"+filledStripeAbove = Cons "filledcurves above"+filledStripeBelow = Cons "filledcurves below" toString :: T x y a -> String
src/Graphics/Gnuplot/Private/Graph3D.hs view
@@ -65,6 +65,9 @@ defltOptions = defltOptions +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
src/Graphics/Gnuplot/Private/Graph3DType.hs view
@@ -12,6 +12,13 @@ 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 -}@@ -23,6 +30,8 @@ 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
src/Graphics/Gnuplot/Private/Plot.hs view
@@ -3,39 +3,53 @@ 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 qualified Data.Foldable as Fold-import qualified Data.Monoid.State as State+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 Control.Monad (liftM2, ) import Data.Monoid (Monoid, mempty, mappend, ) import Data.Maybe (mapMaybe, ) +import qualified System.FilePath as Path+import System.FilePath ((</>), ) + {- | 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 . State.pure+pure = Cons . return {- Could also be implemented with Control.Monad.Trans.State: mappend = liftA2 mappend -} instance Monoid (T graph) where- mempty = Cons mempty+ mempty = Cons $ return mempty mappend (Cons s0) (Cons s1) =- Cons (mappend s0 s1)+ Cons (liftM2 mappend s0 s1) 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 =@@ -49,9 +63,9 @@ graphs_ :: [graph] } -writeData :: File graph -> IO ()-writeData (File fn cont _) =- Fold.mapM_ (writeFile fn) cont+instance FileClass.C (File graph) where+ write (File fn cont _) =+ Fold.mapM_ (writeFile fn) cont tmpFileStem :: FilePath@@ -76,31 +90,34 @@ -} toScript :: Graph.C graph => T graph -> Display.Script 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))+ 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+ [plotCmd p undefined ++ " " ++ commaConcat graphs] optionsToScript :: Graph.C graph => OptionSet.T graph -> Display.Script optionsToScript opts = Display.Script $- State.Cons $ \(n, opts0) ->- let opts1 = OptionSet.decons opts- in (Display.Body [] $- OptionSet.diffToString opts0 opts1,- (n, opts1))+ 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
src/Graphics/Gnuplot/Private/Terminal.hs view
@@ -3,11 +3,15 @@ data T = Cons { options :: [String],- commands :: [String]+ commands :: [String],+ interactive :: Bool } class C terminal where canonical :: terminal -> T -deflt :: T-deflt = Cons ["x11"] []+format :: T -> [String]+format (Cons opts cmds _ia) =+ if null opts+ then cmds+ else (unwords $ "set" : "terminal" : opts) : cmds
src/Graphics/Gnuplot/Simple.hs view
@@ -65,12 +65,16 @@ -} import qualified Graphics.Gnuplot.Private.Terminal as Terminal-import qualified Graphics.Gnuplot.Execute as Exec -import System.Cmd (rawSystem, ) import Graphics.Gnuplot.Utility (quote, commaConcat, semiColonConcat, showTriplet, linearScale, )-import qualified Data.Monoid.State as State++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.Cmd (rawSystem, )+import Control.Functor.HT (void, ) import Data.Foldable (foldMap, ) import Data.Maybe (listToMaybe, mapMaybe, isNothing, ) import Data.List.HT (dropWhileRev, )@@ -338,8 +342,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@@ -365,9 +368,8 @@ attrToProg (Custom attribute parameters) = "set " ++ attribute ++ " " ++ unwords parameters -attrToProg (Terminal (Terminal.Cons options commands)) =- semiColonConcat $- ("set terminal " ++ unwords options) : commands+attrToProg (Terminal term) =+ semiColonConcat $ Terminal.format term attrToProg (EPS filename) = "set terminal postscript eps; " ++ -- latex@@ -428,8 +430,17 @@ showRng (l,r) = "[" ++ show l ++ ":" ++ show r ++ "]" in unwords (map (maybe "[:]" showRng) (dropWhileRev isNothing ranges)) +interactiveTerm :: [Attribute] -> Bool+interactiveTerm =+ all $ \attr ->+ case attr of+ Terminal term -> Terminal.interactive term+ PNG _ -> False+ EPS _ -> False+ _ -> True + plotTypeToGraph :: PlotType -> Graph2D.Type -- GraphType.T plotTypeToGraph t = case t of@@ -520,20 +531,17 @@ Graph.C graph => [Attribute] -> String -> Plot.T graph -> IO () runGnuplot attrs cmd (Plot.Cons mp) =- let files = State.evaluate 0 mp- in do mapM_ Plot.writeData files- callGnuplot attrs cmd $- concatMap (\(Plot.File filename _ grs) ->- map (\gr -> quote filename ++ " " ++ Graph.toString gr) grs) $- files+ 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) -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 ()+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/Default.hs view
@@ -0,0 +1,20 @@+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.options = [],+ Terminal.commands = [],+ Terminal.interactive = True -- Always true? I don't know.+ }
src/Graphics/Gnuplot/Terminal/PNG.hs view
@@ -86,5 +86,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
@@ -91,5 +91,6 @@ (maybe [] (\(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/SVG.hs view
@@ -28,5 +28,6 @@ "svg" : [], Terminal.commands =- ["set output " ++ (quote $ filename_ term)]+ ["set output " ++ (quote $ filename_ term)],+ Terminal.interactive = False }
src/Graphics/Gnuplot/Terminal/WXT.hs view
@@ -47,6 +47,6 @@ (fmap quote $ title_ term) : (fmap (formatBool "persist") $ persist_ term) : []),- Terminal.commands =- []+ Terminal.commands = [],+ Terminal.interactive = True }
src/Graphics/Gnuplot/Terminal/X11.hs view
@@ -43,6 +43,6 @@ (fmap quote $ title_ term) : (fmap (formatBool "persist") $ persist_ term) : []),- Terminal.commands =- []+ Terminal.commands = [],+ Terminal.interactive = True }