diff options
Diffstat (limited to 'packages/gsl/src/Graphics/Plot.hs')
-rw-r--r-- | packages/gsl/src/Graphics/Plot.hs | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/packages/gsl/src/Graphics/Plot.hs b/packages/gsl/src/Graphics/Plot.hs new file mode 100644 index 0000000..0ea41ac --- /dev/null +++ b/packages/gsl/src/Graphics/Plot.hs | |||
@@ -0,0 +1,184 @@ | |||
1 | ----------------------------------------------------------------------------- | ||
2 | -- | | ||
3 | -- Module : Graphics.Plot | ||
4 | -- Copyright : (c) Alberto Ruiz 2005-8 | ||
5 | -- License : GPL-style | ||
6 | -- | ||
7 | -- Maintainer : Alberto Ruiz (aruiz at um dot es) | ||
8 | -- Stability : provisional | ||
9 | -- Portability : uses gnuplot and ImageMagick | ||
10 | -- | ||
11 | -- This module is deprecated. It can be replaced by improved drawing tools | ||
12 | -- available in the plot\\plot-gtk packages by Vivian McPhail or Gnuplot by Henning Thielemann. | ||
13 | ----------------------------------------------------------------------------- | ||
14 | {-# OPTIONS_HADDOCK hide #-} | ||
15 | |||
16 | module Graphics.Plot( | ||
17 | |||
18 | mplot, | ||
19 | |||
20 | plot, parametricPlot, | ||
21 | |||
22 | splot, mesh, meshdom, | ||
23 | |||
24 | matrixToPGM, imshow, | ||
25 | |||
26 | gnuplotX, gnuplotpdf, gnuplotWin | ||
27 | |||
28 | ) where | ||
29 | |||
30 | import Numeric.Container | ||
31 | import Data.List(intersperse) | ||
32 | import System.Process (system) | ||
33 | |||
34 | -- | From vectors x and y, it generates a pair of matrices to be used as x and y arguments for matrix functions. | ||
35 | meshdom :: Vector Double -> Vector Double -> (Matrix Double , Matrix Double) | ||
36 | meshdom r1 r2 = (outer r1 (constant 1 (dim r2)), outer (constant 1 (dim r1)) r2) | ||
37 | |||
38 | |||
39 | {- | Draws a 3D surface representation of a real matrix. | ||
40 | |||
41 | > > mesh $ build (10,10) (\\i j -> i + (j-5)^2) | ||
42 | |||
43 | In certain versions you can interactively rotate the graphic using the mouse. | ||
44 | |||
45 | -} | ||
46 | mesh :: Matrix Double -> IO () | ||
47 | mesh m = gnuplotX (command++dat) where | ||
48 | command = "splot "++datafollows++" matrix with lines\n" | ||
49 | dat = prep $ toLists m | ||
50 | |||
51 | {- | Draws the surface represented by the function f in the desired ranges and number of points, internally using 'mesh'. | ||
52 | |||
53 | > > let f x y = cos (x + y) | ||
54 | > > splot f (0,pi) (0,2*pi) 50 | ||
55 | |||
56 | -} | ||
57 | splot :: (Matrix Double->Matrix Double->Matrix Double) -> (Double,Double) -> (Double,Double) -> Int -> IO () | ||
58 | splot f rx ry n = mesh z where | ||
59 | (x,y) = meshdom (linspace n rx) (linspace n ry) | ||
60 | z = f x y | ||
61 | |||
62 | {- | plots several vectors against the first one | ||
63 | |||
64 | > > let t = linspace 100 (-3,3) in mplot [t, sin t, exp (-t^2)] | ||
65 | |||
66 | -} | ||
67 | mplot :: [Vector Double] -> IO () | ||
68 | mplot m = gnuplotX (commands++dats) where | ||
69 | commands = if length m == 1 then command1 else commandmore | ||
70 | command1 = "plot "++datafollows++" with lines\n" ++ dat | ||
71 | commandmore = "plot " ++ plots ++ "\n" | ||
72 | plots = concat $ intersperse ", " (map cmd [2 .. length m]) | ||
73 | cmd k = datafollows++" using 1:"++show k++" with lines" | ||
74 | dat = prep $ toLists $ fromColumns m | ||
75 | dats = concat (replicate (length m-1) dat) | ||
76 | |||
77 | |||
78 | {- | Draws a list of functions over a desired range and with a desired number of points | ||
79 | |||
80 | > > plot [sin, cos, sin.(3*)] (0,2*pi) 1000 | ||
81 | |||
82 | -} | ||
83 | plot :: [Vector Double->Vector Double] -> (Double,Double) -> Int -> IO () | ||
84 | plot fs rx n = mplot (x: mapf fs x) | ||
85 | where x = linspace n rx | ||
86 | mapf gs y = map ($ y) gs | ||
87 | |||
88 | {- | Draws a parametric curve. For instance, to draw a spiral we can do something like: | ||
89 | |||
90 | > > parametricPlot (\t->(t * sin t, t * cos t)) (0,10*pi) 1000 | ||
91 | |||
92 | -} | ||
93 | parametricPlot :: (Vector Double->(Vector Double,Vector Double)) -> (Double, Double) -> Int -> IO () | ||
94 | parametricPlot f rt n = mplot [fx, fy] | ||
95 | where t = linspace n rt | ||
96 | (fx,fy) = f t | ||
97 | |||
98 | |||
99 | -- | writes a matrix to pgm image file | ||
100 | matrixToPGM :: Matrix Double -> String | ||
101 | matrixToPGM m = header ++ unlines (map unwords ll) where | ||
102 | c = cols m | ||
103 | r = rows m | ||
104 | header = "P2 "++show c++" "++show r++" "++show (round maxgray :: Int)++"\n" | ||
105 | maxgray = 255.0 | ||
106 | maxval = maxElement m | ||
107 | minval = minElement m | ||
108 | scale' = if maxval == minval | ||
109 | then 0.0 | ||
110 | else maxgray / (maxval - minval) | ||
111 | f x = show ( round ( scale' *(x - minval) ) :: Int ) | ||
112 | ll = map (map f) (toLists m) | ||
113 | |||
114 | -- | imshow shows a representation of a matrix as a gray level image using ImageMagick's display. | ||
115 | imshow :: Matrix Double -> IO () | ||
116 | imshow m = do | ||
117 | _ <- system $ "echo \""++ matrixToPGM m ++"\"| display -antialias -resize 300 - &" | ||
118 | return () | ||
119 | |||
120 | ---------------------------------------------------- | ||
121 | |||
122 | gnuplotX :: String -> IO () | ||
123 | gnuplotX command = do { _ <- system cmdstr; return()} where | ||
124 | cmdstr = "echo \""++command++"\" | gnuplot -persist" | ||
125 | |||
126 | datafollows = "\\\"-\\\"" | ||
127 | |||
128 | prep = (++"e\n\n") . unlines . map (unwords . map show) | ||
129 | |||
130 | |||
131 | gnuplotpdf :: String -> String -> [([[Double]], String)] -> IO () | ||
132 | gnuplotpdf title command ds = gnuplot (prelude ++ command ++" "++ draw) >> postproc where | ||
133 | prelude = "set terminal epslatex color; set output '"++title++".tex';" | ||
134 | (dats,defs) = unzip ds | ||
135 | draw = concat (intersperse ", " (map ("\"-\" "++) defs)) ++ "\n" ++ | ||
136 | concatMap pr dats | ||
137 | postproc = do | ||
138 | _ <- system $ "epstopdf "++title++".eps" | ||
139 | mklatex | ||
140 | _ <- system $ "pdflatex "++title++"aux.tex > /dev/null" | ||
141 | _ <- system $ "pdfcrop "++title++"aux.pdf > /dev/null" | ||
142 | _ <- system $ "mv "++title++"aux-crop.pdf "++title++".pdf" | ||
143 | _ <- system $ "rm "++title++"aux.* "++title++".eps "++title++".tex" | ||
144 | return () | ||
145 | |||
146 | mklatex = writeFile (title++"aux.tex") $ | ||
147 | "\\documentclass{article}\n"++ | ||
148 | "\\usepackage{graphics}\n"++ | ||
149 | "\\usepackage{nopageno}\n"++ | ||
150 | "\\usepackage{txfonts}\n"++ | ||
151 | "\\renewcommand{\\familydefault}{phv}\n"++ | ||
152 | "\\usepackage[usenames]{color}\n"++ | ||
153 | |||
154 | "\\begin{document}\n"++ | ||
155 | |||
156 | "\\begin{center}\n"++ | ||
157 | " \\input{./"++title++".tex}\n"++ | ||
158 | "\\end{center}\n"++ | ||
159 | |||
160 | "\\end{document}" | ||
161 | |||
162 | pr = (++"e\n") . unlines . map (unwords . map show) | ||
163 | |||
164 | gnuplot cmd = do | ||
165 | writeFile "gnuplotcommand" cmd | ||
166 | _ <- system "gnuplot gnuplotcommand" | ||
167 | _ <- system "rm gnuplotcommand" | ||
168 | return () | ||
169 | |||
170 | gnuplotWin :: String -> String -> [([[Double]], String)] -> IO () | ||
171 | gnuplotWin title command ds = gnuplot (prelude ++ command ++" "++ draw) where | ||
172 | (dats,defs) = unzip ds | ||
173 | draw = concat (intersperse ", " (map ("\"-\" "++) defs)) ++ "\n" ++ | ||
174 | concatMap pr dats | ||
175 | |||
176 | pr = (++"e\n") . unlines . map (unwords . map show) | ||
177 | |||
178 | prelude = "set title \""++title++"\";" | ||
179 | |||
180 | gnuplot cmd = do | ||
181 | writeFile "gnuplotcommand" cmd | ||
182 | _ <- system "gnuplot -persist gnuplotcommand" | ||
183 | _ <- system "rm gnuplotcommand" | ||
184 | return () | ||