module Graphics.Rendering.HPlot.Hist (
hist
, hist'
, freedmanDiaconis
, squareRoot
, riceRule
)where
import qualified Data.Foldable as F
import qualified Data.Vector as V
import Graphics.Rendering.Chart.Backend.Cairo
import Graphics.Rendering.Chart.Gtk
import Graphics.Rendering.Chart
import Control.Lens
import Data.Default
import Graphics.Rendering.HPlot.Types
import Graphics.Rendering.HPlot.Bars
import Graphics.Rendering.HPlot.Plot
import Graphics.Rendering.HPlot.Utils
convertOpt ∷ HistOption → (PlotOption, BarOption)
convertOpt opt = (
title .~ opt^.title
$ xlab .~ opt^.xlab
$ ylab .~ opt^.ylab
$ xlim .~ opt^.xlim
$ ylim .~ opt^.ylim
$ width .~ opt^.width
$ height .~ opt^.height
$ grid .~ opt^.grid
$ def,
opacity .~ opt^.opacity
$ cols .~ [opt^.col]
$ align .~ BarsLeft
$ space .~ 0
$ def)
hist_ ∷ F.Foldable f ⇒ HistOption → f Double → EitherLayout
hist_ opt xs' = mapped.layout_x_axis.laxis_generate .~ const xAxis $ plot_ popt [bs]
where
(popt, bopt) = convertOpt opt
bs = bars bopt (Just labels', [counts])
xs = F.toList xs'
numBins = (opt^.breaks) xs
labels' = autoSteps numBins xs
counts = V.toList $ histogram_ (length labels' 1) (minimum labels') (maximum labels') (V.fromList xs)
xAxis ∷ AxisData Double
xAxis = AxisData {
_axis_visibility = def,
_axis_viewport = vmap (min', max'),
_axis_tropweiv = invmap (min', max'),
_axis_ticks = [ (v,5) | v ← newLabels ],
_axis_grid = labels',
_axis_labels = [[ (v, show v) | v ← newLabels ]]
}
where
newLabels = let k = ceiling ((fromIntegral (length labels') / 5) ∷ Double)
l = filter (\(i,_) → (i `mod` k) == 0) $ zip [(1∷Int)..] labels'
in snd $ unzip l
halfW = (labels'!!1 head labels') / 2
min' = minimum labels' halfW
max' = maximum labels' + halfW
hist ∷ F.Foldable f ⇒ HistOption → f Double → IO ()
hist opt xs = either f f (hist_ opt xs)
where f x = renderableToWindow (toRenderable x) (opt^.width) (opt^.height)
hist' ∷ F.Foldable f ⇒ HistOption → f Double → String → IO (PickFn ())
hist' opt xs = either f f (hist_ opt xs)
where
f x = renderableToFile
(fo_size .~ (opt^.width, opt^.height) $ def)
(toRenderable x)