Ok, I'm getting stumped by the Haskell Chart library. I've figured out this way to make a log-log line chart of a Vector
of values in Kronos Haskell:
import Data.Vector (Vector, (!))
import qualified Data.Vector as V
import Graphics.Rendering.Chart.Easy hiding (Vector)
logLogChart name points = toRenderable $ execEC $ plot chart
where chart = line name [V.toList $ V.imap makePoint points]
makePoint x y = (LogValue (fromIntegral (x+1)), LogValue y)
This certainly does render a reasonable log-log line chart, with automatically chosen ranges for the x and y axes based on the data. One example (as rendered in Kronos Haskell):
The problem is that I have a specialized application where I need these two things:
Vector
, this could be simplified to have the range of the y-axis determined by that of the x-axis.)I tried looking through the documentation for the library, but it's just got me completely stumped. Any pointers?
This will do but could be vastly improved (not least by removing the unsafePerformIO).
{-# OPTIONS_GHC -Wall #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
import Graphics.Rendering.Chart hiding ( translate )
import Graphics.Rendering.Chart.Backend.Diagrams
import Diagrams.Backend.Cairo.CmdLine
import Diagrams.Prelude hiding ( render, Renderable )
import Data.Default.Class
import Diagrams.Backend.CmdLine
import System.IO.Unsafe
pointVals :: [(Double, Double)]
pointVals = map (\(x,y) -> (log x, log y)) [(1,10), (10, 100), (100, 1000)]
dataPts :: PlotPoints Double Double
dataPts = plot_points_style .~ filledCircles 2 (opaque red)
$ plot_points_values .~ pointVals
$ plot_points_title .~ "Data points"
$ def
layout :: Layout Double Double
layout = layout_title .~ "Log vs Log"
$ layout_y_axis . laxis_generate .~ scaledAxis def (0,10)
$ layout_x_axis . laxis_generate .~ scaledAxis def (0,10)
$ layout_plots .~ [toPlot dataPts]
$ def
myChart :: Renderable ()
myChart = toRenderable layout
denv :: DEnv
denv = unsafePerformIO $ defaultEnv vectorAlignmentFns 500 500
displayHeader :: FilePath -> Diagram B R2 -> IO ()
displayHeader fn =
mainRender ( DiagramOpts (Just 900) (Just 700) fn
, DiagramLoopOpts False Nothing 0
)
myDiagram :: Diagram Cairo R2
myDiagram = fst $ runBackend denv (render myChart (500, 500))
main :: IO ()
main = displayHeader "LogChart.png" myDiagram