a50-0.2: src/Gnuplot.hs
module Gnuplot where
import System.Process
import System.Exit
import System.IO
import Data.List (intersperse)
import Control.Monad (when)
import System.Directory (findExecutable)
import Control.Concurrent (forkIO)
gnuplot :: Num i => [String] -> [(String,[i])] -> [Int] -> IO ()
gnuplot preamble cols hlines = do
fe <- findExecutable "gnuplot"
when (fe == Nothing) $ error "Couldn't find the 'gnuplot' executable - aborting"
(i,o,e,p) <- runInteractiveCommand "gnuplot -persist"
_ <- forkIO (hGetContents o >>= hPutStr stdout)
-- ugly hack to limit error output
_ <- forkIO $ do
let go ~(l1:l2:ls) =do putStrLn l1
if ('^' `elem` l1)
then do
putStrLn l2
else go (l2:ls)
go =<< fmap lines (hGetContents e)
hPutStr i $ unlines $ preamble
hPutStrLn i (mkplots cols ++ concatMap ((',':) . show) hlines)
mapM_ (\col -> do {hPutStr i . unlines . map show . snd $ col; hPutStrLn i "e"}) cols
hClose i
x <- waitForProcess p
case x of ExitSuccess -> return ()
ExitFailure j -> hPutStrLn stderr (errmsg++show j) >> return ()
where errmsg = "'gnuplot' failed with exit code "
-- | generate the plot command
mkplots :: [(String,[a])] -> String
mkplots cs = "plot " ++ (concat . intersperse "," . map mkp $ cs)
where mkp :: (String,a) -> String
mkp (s,_) = "'-' with lines title '"++s++"'"