Histogram
Histogram
Renders a histogram of a randomly generated data set
module Histogram exposing (main)
import Random.Pcg as Random exposing (Generator, Seed)
import Visualization.Histogram as Histogram exposing (Bin, HistogramGenerator)
import Visualization.List as List
import Svg exposing (..)
import Svg.Attributes exposing (..)
import Visualization.Axis as Axis exposing (defaultOptions)
import Visualization.Scale as Scale exposing (BandConfig, BandScale, ContinuousScale, defaultBandConfig)
{-| We use addition here to approximate normal distribution.
-}
generator : Generator (List Float)
generator =
Random.list 500 <| Random.map2 (+) (Random.float 0 10) (Random.float 0 10)
seed : Seed
seed =
Random.initialSeed 227852860
model : List Float
model =
Tuple.first <| Random.step generator seed
histogram : List Float -> List (Bin Float Float)
histogram model =
Histogram.float
|> Histogram.withDomain ( 0, 20 )
|> Histogram.compute model
w : Float
w =
900
h : Float
h =
450
padding : Float
padding =
30
xScale : ContinuousScale
xScale =
Scale.linear ( 0, 20 ) ( 0, w - 2 * padding )
yScale : List (Bin Float Float) -> ContinuousScale
yScale bins =
List.map .length bins
|> List.maximum
|> Maybe.withDefault 0
|> toFloat
|> (,) 0
|> flip Scale.linear ( h - 2 * padding, 0 )
xAxis : List Float -> Svg msg
xAxis model =
Axis.axis { defaultOptions | orientation = Axis.Bottom } xScale
yAxis : List (Bin Float Float) -> Svg msg
yAxis bins =
Axis.axis { defaultOptions | orientation = Axis.Left, tickCount = 5 } (yScale bins)
column : ContinuousScale -> ContinuousScale -> Bin Float Float -> Svg msg
column xScale yScale { length, x0, x1 } =
rect
[ x <| toString <| Scale.convert xScale x0
, y <| toString <| Scale.convert yScale (toFloat length)
, width <| toString <| Scale.convert xScale x1 - Scale.convert xScale x0
, height <| toString <| h - Scale.convert yScale (toFloat <| Debug.log "length" length) - 2 * padding
, stroke "none"
, fill "rgb(46, 118, 149)"
]
[]
view : List Float -> Svg msg
view model =
let
bins =
Debug.log "bins" <| histogram model
in
svg [ width (toString w ++ "px"), height (toString h ++ "px") ]
[ g [ transform ("translate(" ++ toString (padding - 1) ++ ", " ++ toString (h - padding) ++ ")") ]
[ xAxis model ]
, g [ transform ("translate(" ++ toString (padding - 1) ++ ", " ++ toString padding ++ ")") ]
[ yAxis bins ]
, g [ transform ("translate(" ++ toString padding ++ ", " ++ toString padding ++ ")"), class "series" ] <|
List.map (column xScale (yScale bins)) bins
]
main =
view model