module Amby.Plot
( plot
, plotEq
, getEC
, save
, saveSvg
, cairoDefSave
, diagramsDefSave
) where
import Control.Arrow
import Control.Monad
import Control.Monad.State
import qualified Data.List as L
import qualified Data.Vector.Generic as G
import Data.Default.Class
import Graphics.Rendering.Chart.Easy hiding (plot)
import qualified Graphics.Rendering.Chart.Easy as Chart
import qualified Graphics.Rendering.Chart.Backend.Cairo as Cairo
import qualified Graphics.Rendering.Chart.Backend.Diagrams as Diagrams
import Lens.Micro
import Statistics.Distribution
import Amby.Types
import Amby.Numeric
import Amby.Theme
import Amby.Style
cairoDefSave :: FilePath
cairoDefSave = ".__amby.png"
diagramsDefSave :: FilePath
diagramsDefSave = ".__amby.svg"
getEC :: AmbyChart () -> EC (Layout Double Double) ()
getEC compute = getLayout $ execState compute def
getState :: AmbyChart () -> AmbyState
getState compute = execState compute def
save :: AmbyChart () -> IO ()
save chart = Cairo.toFile
def { Cairo._fo_size = size }
cairoDefSave
(getLayout st)
where
st = getState chart
size = getSize st
saveSvg :: AmbyChart () -> IO ()
saveSvg chart = Diagrams.toFile
def { Diagrams._fo_size = join (***) fromIntegral size }
diagramsDefSave
(getLayout st)
where
st = getState chart
size = getSize st
instance (G.Vector v Double, G.Vector v (Double, Double))
=> AmbyContainer (v Double) Double where
plot :: v Double -> v Double -> AmbyChart ()
plot x y = plotList $ G.toList (G.zip x y)
plotEq :: v Double -> (Double -> Double) -> AmbyChart ()
plotEq x fn = plotList $ G.toList (G.zip x (G.map fn x))
instance (Real a) => AmbyContainer [a] a where
plot :: [a] -> [a] -> AmbyChart ()
plot x y = plotList $ L.zipWith (\a b -> (realToFrac a, realToFrac b)) x y
plotEq x fn = plotList $ L.zipWith (\a b -> (realToFrac a, realToFrac b)) x (map fn x)
plotList :: [(Double, Double)] -> AmbyChart ()
plotList plotVals = do
theme <- takeTheme
layout <- takeLayout
putLayout $ layout >> mkLayout theme
where
linePlot :: EC l (PlotLines Double Double)
linePlot = liftEC $ do
nextColor <- takeColor
plot_lines_values .= [plotVals]
plot_lines_style . line_width .= 2.5
plot_lines_style . line_color .= nextColor
mkLayout :: Theme -> EC (Layout Double Double) ()
mkLayout theme = do
Chart.plot linePlot