{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
{-# OPTIONS_HADDOCK hide #-}
module Graphics.Plot(
mplot,
plot, parametricPlot,
splot, mesh, meshdom,
matrixToPGM, imshow,
gnuplotX, gnuplotpdf, gnuplotWin
) where
import Numeric.LinearAlgebra.HMatrix
import Data.List(intersperse)
import System.Process (system)
meshdom :: Vector Double -> Vector Double -> (Matrix Double , Matrix Double)
meshdom :: Vector Double -> Vector Double -> (Matrix Double, Matrix Double)
meshdom r1 :: Vector Double
r1 r2 :: Vector Double
r2 = (Vector Double -> Vector Double -> Matrix Double
forall t. Product t => Vector t -> Vector t -> Matrix t
outer Vector Double
r1 (Double -> Int -> Vector Double
forall e d (c :: * -> *). Konst e d c => e -> d -> c e
konst 1 (Vector Double -> IndexOf Vector
forall (c :: * -> *) t. Container c t => c t -> IndexOf c
size Vector Double
r2)), Vector Double -> Vector Double -> Matrix Double
forall t. Product t => Vector t -> Vector t -> Matrix t
outer (Double -> Int -> Vector Double
forall e d (c :: * -> *). Konst e d c => e -> d -> c e
konst 1 (Vector Double -> IndexOf Vector
forall (c :: * -> *) t. Container c t => c t -> IndexOf c
size Vector Double
r1)) Vector Double
r2)
mesh :: Matrix Double -> IO ()
mesh :: Matrix Double -> IO ()
mesh m :: Matrix Double
m = String -> IO ()
gnuplotX (String
commandString -> String -> String
forall a. [a] -> [a] -> [a]
++String
dat) where
command :: String
command = "splot "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
datafollowsString -> String -> String
forall a. [a] -> [a] -> [a]
++" matrix with lines\n"
dat :: String
dat = [[Double]] -> String
prep ([[Double]] -> String) -> [[Double]] -> String
forall a b. (a -> b) -> a -> b
$ Matrix Double -> [[Double]]
forall t. Element t => Matrix t -> [[t]]
toLists Matrix Double
m
splot :: (Matrix Double->Matrix Double->Matrix Double) -> (Double,Double) -> (Double,Double) -> Int -> IO ()
splot :: (Matrix Double -> Matrix Double -> Matrix Double)
-> (Double, Double) -> (Double, Double) -> Int -> IO ()
splot f :: Matrix Double -> Matrix Double -> Matrix Double
f rx :: (Double, Double)
rx ry :: (Double, Double)
ry n :: Int
n = Matrix Double -> IO ()
mesh Matrix Double
z where
(x :: Matrix Double
x,y :: Matrix Double
y) = Vector Double -> Vector Double -> (Matrix Double, Matrix Double)
meshdom (Int -> (Double, Double) -> Vector Double
forall e.
(Fractional e, Container Vector e) =>
Int -> (e, e) -> Vector e
linspace Int
n (Double, Double)
rx) (Int -> (Double, Double) -> Vector Double
forall e.
(Fractional e, Container Vector e) =>
Int -> (e, e) -> Vector e
linspace Int
n (Double, Double)
ry)
z :: Matrix Double
z = Matrix Double -> Matrix Double -> Matrix Double
f Matrix Double
x Matrix Double
y
mplot :: [Vector Double] -> IO ()
mplot :: [Vector Double] -> IO ()
mplot m :: [Vector Double]
m = String -> IO ()
gnuplotX (String
commandsString -> String -> String
forall a. [a] -> [a] -> [a]
++String
dats) where
commands :: String
commands = if [Vector Double] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Vector Double]
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1 then String
command1 else String
commandmore
command1 :: String
command1 = "plot "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
datafollowsString -> String -> String
forall a. [a] -> [a] -> [a]
++" with lines\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
dat
commandmore :: String
commandmore = "plot " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
plots String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\n"
plots :: String
plots = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse ", " ((Int -> String) -> [Int] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Int -> String
forall a. Show a => a -> String
cmd [2 .. [Vector Double] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Vector Double]
m])
cmd :: a -> String
cmd k :: a
k = String
datafollowsString -> String -> String
forall a. [a] -> [a] -> [a]
++" using 1:"String -> String -> String
forall a. [a] -> [a] -> [a]
++a -> String
forall a. Show a => a -> String
show a
kString -> String -> String
forall a. [a] -> [a] -> [a]
++" with lines"
dat :: String
dat = [[Double]] -> String
prep ([[Double]] -> String) -> [[Double]] -> String
forall a b. (a -> b) -> a -> b
$ Matrix Double -> [[Double]]
forall t. Element t => Matrix t -> [[t]]
toLists (Matrix Double -> [[Double]]) -> Matrix Double -> [[Double]]
forall a b. (a -> b) -> a -> b
$ [Vector Double] -> Matrix Double
forall t. Element t => [Vector t] -> Matrix t
fromColumns [Vector Double]
m
dats :: String
dats = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Int -> String -> [String]
forall a. Int -> a -> [a]
replicate ([Vector Double] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Vector Double]
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) String
dat)
plot :: [Vector Double->Vector Double] -> (Double,Double) -> Int -> IO ()
plot :: [Vector Double -> Vector Double]
-> (Double, Double) -> Int -> IO ()
plot fs :: [Vector Double -> Vector Double]
fs rx :: (Double, Double)
rx n :: Int
n = [Vector Double] -> IO ()
mplot (Vector Double
xVector Double -> [Vector Double] -> [Vector Double]
forall a. a -> [a] -> [a]
: [Vector Double -> Vector Double]
-> Vector Double -> [Vector Double]
forall a b. [a -> b] -> a -> [b]
mapf [Vector Double -> Vector Double]
fs Vector Double
x)
where x :: Vector Double
x = Int -> (Double, Double) -> Vector Double
forall e.
(Fractional e, Container Vector e) =>
Int -> (e, e) -> Vector e
linspace Int
n (Double, Double)
rx
mapf :: [a -> b] -> a -> [b]
mapf gs :: [a -> b]
gs y :: a
y = ((a -> b) -> b) -> [a -> b] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ a
y) [a -> b]
gs
parametricPlot :: (Vector Double->(Vector Double,Vector Double)) -> (Double, Double) -> Int -> IO ()
parametricPlot :: (Vector Double -> (Vector Double, Vector Double))
-> (Double, Double) -> Int -> IO ()
parametricPlot f :: Vector Double -> (Vector Double, Vector Double)
f rt :: (Double, Double)
rt n :: Int
n = [Vector Double] -> IO ()
mplot [Vector Double
fx, Vector Double
fy]
where t :: Vector Double
t = Int -> (Double, Double) -> Vector Double
forall e.
(Fractional e, Container Vector e) =>
Int -> (e, e) -> Vector e
linspace Int
n (Double, Double)
rt
(fx :: Vector Double
fx,fy :: Vector Double
fy) = Vector Double -> (Vector Double, Vector Double)
f Vector Double
t
matrixToPGM :: Matrix Double -> String
matrixToPGM :: Matrix Double -> String
matrixToPGM m :: Matrix Double
m = String
header String -> String -> String
forall a. [a] -> [a] -> [a]
++ [String] -> String
unlines (([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map [String] -> String
unwords [[String]]
ll) where
c :: Int
c = Matrix Double -> Int
forall t. Matrix t -> Int
cols Matrix Double
m
r :: Int
r = Matrix Double -> Int
forall t. Matrix t -> Int
rows Matrix Double
m
header :: String
header = "P2 "String -> String -> String
forall a. [a] -> [a] -> [a]
++Int -> String
forall a. Show a => a -> String
show Int
cString -> String -> String
forall a. [a] -> [a] -> [a]
++" "String -> String -> String
forall a. [a] -> [a] -> [a]
++Int -> String
forall a. Show a => a -> String
show Int
rString -> String -> String
forall a. [a] -> [a] -> [a]
++" "String -> String -> String
forall a. [a] -> [a] -> [a]
++Int -> String
forall a. Show a => a -> String
show (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round Double
maxgray :: Int)String -> String -> String
forall a. [a] -> [a] -> [a]
++"\n"
maxgray :: Double
maxgray = 255.0
maxval :: Double
maxval = Matrix Double -> Double
forall (c :: * -> *) e. Container c e => c e -> e
maxElement Matrix Double
m
minval :: Double
minval = Matrix Double -> Double
forall (c :: * -> *) e. Container c e => c e -> e
minElement Matrix Double
m
scale' :: Double
scale' = if Double
maxval Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
minval
then 0.0
else Double
maxgray Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
maxval Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
minval)
f :: Double -> String
f x :: Double
x = Int -> String
forall a. Show a => a -> String
show ( Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round ( Double
scale' Double -> Double -> Double
forall a. Num a => a -> a -> a
*(Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
minval) ) :: Int )
ll :: [[String]]
ll = ([Double] -> [String]) -> [[Double]] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map ((Double -> String) -> [Double] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Double -> String
f) (Matrix Double -> [[Double]]
forall t. Element t => Matrix t -> [[t]]
toLists Matrix Double
m)
imshow :: Matrix Double -> IO ()
imshow :: Matrix Double -> IO ()
imshow m :: Matrix Double
m = do
ExitCode
_ <- String -> IO ExitCode
system (String -> IO ExitCode) -> String -> IO ExitCode
forall a b. (a -> b) -> a -> b
$ "echo \""String -> String -> String
forall a. [a] -> [a] -> [a]
++ Matrix Double -> String
matrixToPGM Matrix Double
m String -> String -> String
forall a. [a] -> [a] -> [a]
++"\"| display -antialias -resize 300 - &"
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
gnuplotX :: String -> IO ()
gnuplotX :: String -> IO ()
gnuplotX command :: String
command = do { ExitCode
_ <- String -> IO ExitCode
system String
cmdstr; () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return()} where
cmdstr :: String
cmdstr = "echo \""String -> String -> String
forall a. [a] -> [a] -> [a]
++String
commandString -> String -> String
forall a. [a] -> [a] -> [a]
++"\" | gnuplot -persist"
datafollows :: String
datafollows = "\\\"-\\\""
prep :: [[Double]] -> String
prep = (String -> String -> String
forall a. [a] -> [a] -> [a]
++"e\n\n") (String -> String)
-> ([[Double]] -> String) -> [[Double]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
unlines ([String] -> String)
-> ([[Double]] -> [String]) -> [[Double]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Double] -> String) -> [[Double]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ([String] -> String
unwords ([String] -> String)
-> ([Double] -> [String]) -> [Double] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> String) -> [Double] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Double -> String
forall a. Show a => a -> String
show)
gnuplotpdf :: String -> String -> [([[Double]], String)] -> IO ()
gnuplotpdf :: String -> String -> [([[Double]], String)] -> IO ()
gnuplotpdf title :: String
title command :: String
command ds :: [([[Double]], String)]
ds = String -> IO ()
gnuplot (String
prelude String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
command String -> String -> String
forall a. [a] -> [a] -> [a]
++" "String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
draw) IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
postproc where
prelude :: String
prelude = "set terminal epslatex color; set output '"String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++".tex';"
(dats :: [[[Double]]]
dats,defs :: [String]
defs) = [([[Double]], String)] -> ([[[Double]]], [String])
forall a b. [(a, b)] -> ([a], [b])
unzip [([[Double]], String)]
ds
draw :: String
draw = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse ", " ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ("\"-\" "String -> String -> String
forall a. [a] -> [a] -> [a]
++) [String]
defs)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
([[Double]] -> String) -> [[[Double]]] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [[Double]] -> String
pr [[[Double]]]
dats
postproc :: IO ()
postproc = do
ExitCode
_ <- String -> IO ExitCode
system (String -> IO ExitCode) -> String -> IO ExitCode
forall a b. (a -> b) -> a -> b
$ "epstopdf "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++".eps"
IO ()
mklatex
ExitCode
_ <- String -> IO ExitCode
system (String -> IO ExitCode) -> String -> IO ExitCode
forall a b. (a -> b) -> a -> b
$ "pdflatex "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++"aux.tex > /dev/null"
ExitCode
_ <- String -> IO ExitCode
system (String -> IO ExitCode) -> String -> IO ExitCode
forall a b. (a -> b) -> a -> b
$ "pdfcrop "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++"aux.pdf > /dev/null"
ExitCode
_ <- String -> IO ExitCode
system (String -> IO ExitCode) -> String -> IO ExitCode
forall a b. (a -> b) -> a -> b
$ "mv "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++"aux-crop.pdf "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++".pdf"
ExitCode
_ <- String -> IO ExitCode
system (String -> IO ExitCode) -> String -> IO ExitCode
forall a b. (a -> b) -> a -> b
$ "rm "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++"aux.* "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++".eps "String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++".tex"
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
mklatex :: IO ()
mklatex = String -> String -> IO ()
writeFile (String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++"aux.tex") (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
"\\documentclass{article}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\usepackage{graphics}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\usepackage{nopageno}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\usepackage{txfonts}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\renewcommand{\\familydefault}{phv}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\usepackage[usenames]{color}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\begin{document}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\begin{center}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
" \\input{./"String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++".tex}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\end{center}\n"String -> String -> String
forall a. [a] -> [a] -> [a]
++
"\\end{document}"
pr :: [[Double]] -> String
pr = (String -> String -> String
forall a. [a] -> [a] -> [a]
++"e\n") (String -> String)
-> ([[Double]] -> String) -> [[Double]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
unlines ([String] -> String)
-> ([[Double]] -> [String]) -> [[Double]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Double] -> String) -> [[Double]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ([String] -> String
unwords ([String] -> String)
-> ([Double] -> [String]) -> [Double] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> String) -> [Double] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Double -> String
forall a. Show a => a -> String
show)
gnuplot :: String -> IO ()
gnuplot cmd :: String
cmd = do
String -> String -> IO ()
writeFile "gnuplotcommand" String
cmd
ExitCode
_ <- String -> IO ExitCode
system "gnuplot gnuplotcommand"
ExitCode
_ <- String -> IO ExitCode
system "rm gnuplotcommand"
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
gnuplotWin :: String -> String -> [([[Double]], String)] -> IO ()
gnuplotWin :: String -> String -> [([[Double]], String)] -> IO ()
gnuplotWin title :: String
title command :: String
command ds :: [([[Double]], String)]
ds = String -> IO ()
gnuplot (String
prelude String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
command String -> String -> String
forall a. [a] -> [a] -> [a]
++" "String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
draw) where
(dats :: [[[Double]]]
dats,defs :: [String]
defs) = [([[Double]], String)] -> ([[[Double]]], [String])
forall a b. [(a, b)] -> ([a], [b])
unzip [([[Double]], String)]
ds
draw :: String
draw = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse ", " ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ("\"-\" "String -> String -> String
forall a. [a] -> [a] -> [a]
++) [String]
defs)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
([[Double]] -> String) -> [[[Double]]] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [[Double]] -> String
pr [[[Double]]]
dats
pr :: [[Double]] -> String
pr = (String -> String -> String
forall a. [a] -> [a] -> [a]
++"e\n") (String -> String)
-> ([[Double]] -> String) -> [[Double]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
unlines ([String] -> String)
-> ([[Double]] -> [String]) -> [[Double]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Double] -> String) -> [[Double]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ([String] -> String
unwords ([String] -> String)
-> ([Double] -> [String]) -> [Double] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> String) -> [Double] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Double -> String
forall a. Show a => a -> String
show)
prelude :: String
prelude = "set title \""String -> String -> String
forall a. [a] -> [a] -> [a]
++String
titleString -> String -> String
forall a. [a] -> [a] -> [a]
++"\";"
gnuplot :: String -> IO ()
gnuplot cmd :: String
cmd = do
String -> String -> IO ()
writeFile "gnuplotcommand" String
cmd
ExitCode
_ <- String -> IO ExitCode
system "gnuplot -persist gnuplotcommand"
ExitCode
_ <- String -> IO ExitCode
system "rm gnuplotcommand"
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()