Skip to content
Tim Docker edited this page Aug 25, 2014 · 4 revisions

Although constructing charts consists of pure operations, a stateful monadic API is available to allow charting code to be more concise. Here is a minimal example:

import Graphics.Rendering.Chart.Easy
import Graphics.Rendering.Chart.Backend.Cairo

signal :: [Double] -> [(Double,Double)]
signal xs = [ (x,(sin (x*3.14159/45) + 1) / 2 * (sin (x*3.14159/5))) | x <- xs ]

main = toFile def "test.png" $ plot $ line "lines" [signal [0,(0.5)..400]]

The Easy module imports the functions and datatypes for constructing charts, along with a few other necessary 3rd party libs (Control.Lens and Data.Colour). An additional import is required to select the appropriate rendering backend. line produces a line chart with the given label and data points. plot adds this to the layout under construction. toFile from the backend renders the layout to the specified file. def specifies to use default rendering parameters. For the cairo backend this means an 800x600 image in PNG format.

The monadic nature of the API become apparent when more than one item is plotted:

main = toFile def "test.png" $ do
    plot (line "lines" [signal [0,(0.5)..400]])
    plot (points "points" (signal [0,7..400]))

points produces a scatter chart. The two plots will have different colors - each call to {line} or {points} will request a new colour from the monad state.

The layout being generated is part of the state. This means that the state monad functions in the lens library can be used to modify or augment the layout. For example:

main = toFile def "test.png" $ do
    layout . layout_title .= "AM Modulation"
    layout . layout_all_font_styles . font_size %= (*1.5)
    plot (line "lines" [signal [0,(0.5)..400]])
    plot (points "points" (signal [0,7..400]))

will set the title of the plot, and scale all the fonts up.

Changing the rendering output properties can easily be done via the first parameter to toFile:

outProps = fo_size .~ (1024,768)
        $ fo_format .~ PDF
        $ def

main = toFile outProps "test.pdf" $ do
    ...

will produce a PDF file.

All of the examples above construct a Layout and then render it. A value of type Layout x y represents a chart with the associated types for the x and y axes. A value of type LayoutLR x yl yr supports two types of y values, one for the left axis, one for the right. Variants of the plot function are used to support this:

main = toFile def "test.png" $ do
    layout . layoutlr_title .= "AM Modulation"
    plotLeft (line "data 1" [signal [0,(0.5)..400]])
    plotRight (line "data 2" [signal2 [0,(0.5)..400]])

Note that there is no overloading of the lenses to access layout values, hence layoutlr_title above.

Clone this wiki locally