haskell-plot (empty) → 0.1.0.0
raw patch · 13 files changed
+1088/−0 lines, 13 filesdep +Chartdep +Chart-cairodep +Chart-gtksetup-changed
Dependencies added: Chart, Chart-cairo, Chart-gtk, base, colour, data-default, lens, math-functions, vector
Files
- Graphics/Rendering/HPlot.hs +19/−0
- Graphics/Rendering/HPlot/Bars.hs +25/−0
- Graphics/Rendering/HPlot/HeatMap.hs +64/−0
- Graphics/Rendering/HPlot/HeatMap/Internal.hs +71/−0
- Graphics/Rendering/HPlot/Hist.hs +79/−0
- Graphics/Rendering/HPlot/Lines.hs +34/−0
- Graphics/Rendering/HPlot/Plot.hs +67/−0
- Graphics/Rendering/HPlot/Points.hs +39/−0
- Graphics/Rendering/HPlot/Types.hs +224/−0
- Graphics/Rendering/HPlot/Utils.hs +80/−0
- LICENSE +339/−0
- Setup.hs +2/−0
- haskell-plot.cabal +45/−0
+ Graphics/Rendering/HPlot.hs view
@@ -0,0 +1,19 @@+module Graphics.Rendering.HPlot (+ module Graphics.Rendering.HPlot.Hist,+ module Graphics.Rendering.HPlot.Points,+ module Graphics.Rendering.HPlot.Types,+ module Graphics.Rendering.HPlot.Bars,+ module Graphics.Rendering.HPlot.Lines,+ module Graphics.Rendering.HPlot.Plot,+ module Graphics.Rendering.HPlot.Utils,+ module Graphics.Rendering.HPlot.HeatMap+) where++import Graphics.Rendering.HPlot.Plot+import Graphics.Rendering.HPlot.Hist+import Graphics.Rendering.HPlot.Points+import Graphics.Rendering.HPlot.Types+import Graphics.Rendering.HPlot.Bars+import Graphics.Rendering.HPlot.Lines+import Graphics.Rendering.HPlot.Utils+import Graphics.Rendering.HPlot.HeatMap
+ Graphics/Rendering/HPlot/Bars.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax #-}++module Graphics.Rendering.HPlot.Bars where++import qualified Data.Foldable as F+import Graphics.Rendering.Chart+import Control.Lens+import Data.Default+import Graphics.Rendering.HPlot.Types+import Graphics.Rendering.HPlot.Utils+import Data.List+import Data.Maybe++bars ∷ F.Foldable f ⇒ BarOption → (Maybe (f Double), [f Double]) → EitherPlot+bars opt (x, ys) | isNothing x = Left $ toPlot' $ addIndexes ys'+ | otherwise = Right $ toPlot' $ zip (F.toList $ fromJust x) ys'+ where+ toPlot' x_y = plotBars $ plot_bars_values .~ x_y+ $ plot_bars_style .~ opt^.style+ $ plot_bars_titles .~ opt^.legend+ $ plot_bars_item_styles .~ fmap (\c → (FillStyleSolid $ mkColor c (opt^.opacity), Just def)) (cycle (opt^.cols))+ $ plot_bars_spacing .~ BarsFixGap (opt^.space) 0+ $ plot_bars_alignment .~ opt^.align+ $ def+ ys' = transpose $ fmap F.toList ys
+ Graphics/Rendering/HPlot/HeatMap.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax #-}++module Graphics.Rendering.HPlot.HeatMap (+ heatmap+ , heatmap'+) where++import Graphics.Rendering.Chart+import Graphics.Rendering.Chart.Gtk+import Graphics.Rendering.Chart.Backend.Cairo+import Graphics.Rendering.HPlot.HeatMap.Internal+import Graphics.Rendering.HPlot.Types+import Data.Default+import Control.Lens++heatmap_ ∷ HeatMapOption → [[Double]] → Layout Double Double+heatmap_ opt xs = toLayout p+ where+ p = plotHeatMap + $ heat_map_values .~ xs+ $ heat_map_palette .~ opt^.palette+ $ heat_map_opacity .~ opt^.opacity+ $ heat_map_space .~ opt^.space+ $ def++ toLayout p' = + layout_plots .~ [p']+ $ layout_title .~ opt^.title+ $ layout_x_axis .~ (+ laxis_generate .~ axisFn (opt^.labCol)+ $ def+ )+ $ layout_y_axis .~ (+ laxis_generate .~ axisFn (opt^.labRow)+ $ def+ )+ $ def++ axisFn labs ps = mkHeatMapAxis labs ps' (l, u)+ where+ ps' = drop 2 ps+ [l, u] = take 2 ps++heatmap ∷ HeatMapOption → [[Double]] → IO ()+heatmap opt xs = renderableToWindow (toRenderable layout) (opt^.width) (opt^.height)+ where+ layout = heatmap_ opt xs++heatmap' ∷ HeatMapOption → [[Double]] → String → IO ()+heatmap' opt xs flname = + renderableToFile (fo_size .~ (opt^.width, opt^.height) $ def)+ (toRenderable layout) flname >> return ()+ where+ layout = heatmap_ opt xs++mkHeatMapAxis ∷ [String] → [Double] → (Double, Double) → AxisData Double+mkHeatMapAxis labs labelvs range = AxisData {+ _axis_visibility = def,+ _axis_viewport = vmap range,+ _axis_tropweiv = invmap range,+ _axis_ticks = [ (v, -5) | v ← labelvs ],+ _axis_grid = [],+ _axis_labels = [zip labelvs labs]+}
+ Graphics/Rendering/HPlot/HeatMap/Internal.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax, TemplateHaskell #-}++module Graphics.Rendering.HPlot.HeatMap.Internal where++import Control.Monad+import Data.Colour+import Data.Default+import Graphics.Rendering.Chart+import Control.Lens++data HeatMap x = HeatMap {+ _heat_map_palette ∷ [Colour Double]+ , _heat_map_opacity ∷ Double+ , _heat_map_space ∷ Double+ -- | The matrix to be plotted+ , _heat_map_values ∷ [[x]]+}++makeLenses ''HeatMap++instance Default (HeatMap x) where+ def = HeatMap {+ _heat_map_palette = []+ , _heat_map_opacity = 1+ , _heat_map_space = 1+ , _heat_map_values = [[]]+ }++plotHeatMap ∷ PlotValue x ⇒ HeatMap x → Plot Double Double+plotHeatMap p = Plot {+ _plot_render = renderHeatMap p,+ _plot_legend = [],+ _plot_all_points = diagPoints p+}++renderHeatMap ∷ PlotValue x ⇒ HeatMap x → PointMapFn Double Double → ChartBackend ()+renderHeatMap p pmap = forM_ sqrs (\ ((i, j), y) → do+ let fstyle = FillStyleSolid $ withOpacity + (_heat_map_palette p !! scale' (toValue y))+ (_heat_map_opacity p)+ withFillStyle fstyle $ do+ pth ← alignStrokePath (sqrPath i j)+ fillPath pth+ )+ where+ sqrPath i j = let (x1, y1) = (i * (size + space), j * (size + space))+ p1 = mapXY pmap (x1, y1)+ p2 = mapXY pmap (x1 + size, y1 + size)+ in rectPath (Rect p1 p2)++ nrows = fromIntegral $ length vals+ ncols = fromIntegral $ length $ head vals+ sqrs = zip [ (i, j) | j ← [nrows-1,nrows-2..0], i ← [0..ncols-1] ] vals'+ vals = _heat_map_values p+ vals' = concat vals+ size = 15+ space = _heat_map_space p+ min' = toValue $ minimum vals'+ max' = toValue $ maximum vals'+ n = fromIntegral $ length $ _heat_map_palette p+ scale' v = round $ (n - 1) * (v - min') / (max' - min')++diagPoints ∷ HeatMap x → ([Double], [Double])+diagPoints p = (0 : ncols * size + (ncols-1) * space : xs, 0 : nrows * size + (nrows-1) * space : ys)+ where+ (xs, ys) = ([0.5*size,1.5*size+space..(ncols-1)*(size+space)+0.5*size], [0.5*size,1.5*size+space..(nrows-1)*(size+space)+0.5*size])+ nrows = fromIntegral $ length vals+ ncols = fromIntegral $ length $ head vals+ vals = _heat_map_values p+ size = 15+ space = _heat_map_space p
+ Graphics/Rendering/HPlot/Hist.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax #-}+{-# LANGUAGE FlexibleContexts #-}++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)
+ Graphics/Rendering/HPlot/Lines.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax #-}+{-# LANGUAGE FlexibleContexts #-}++module Graphics.Rendering.HPlot.Lines where++import qualified Data.Foldable as F+import Graphics.Rendering.Chart+import Control.Lens+import Data.Default+import Graphics.Rendering.HPlot.Types+import Graphics.Rendering.HPlot.Utils+import Data.Maybe++toLineStyle ∷ LineOption → LineStyle+toLineStyle opt = line_width .~ opt^.lwd+ $ line_color .~ mkColor (opt^.col) (opt^.opacity)+ $ line_dashes .~ (case opt^.lty of+ 1 → []+ 2 → [5,5]+ 3 → [2,4]+ 4 → [5,3,2,3]+ 5 → [8,3]+ 6 → [8,3,3,3]+ _ → [])+ $ def++line ∷ F.Foldable f ⇒ LineOption → (Maybe (f Double), f Double) → EitherPlot+line opt (x,y) | isNothing x = Left $ mkPlot $ addIndexes y'+ | otherwise = Right $ mkPlot $ zip (F.toList $ fromJust x) y'+ where+ y' = F.toList y+ mkPlot x_y = toPlot $ plot_lines_values .~ [x_y]+ $ plot_lines_style .~ toLineStyle opt+ $ def
+ Graphics/Rendering/HPlot/Plot.hs view
@@ -0,0 +1,67 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax #-}++module Graphics.Rendering.HPlot.Plot (+ plot_+ , plot+ , plot'+ ) where++import Graphics.Rendering.Chart+import Graphics.Rendering.Chart.Backend.Cairo+import Graphics.Rendering.Chart.Gtk+import Graphics.Rendering.HPlot.Types+import Graphics.Rendering.HPlot.Utils+import Control.Lens+import Data.Default+import Data.Either++plot_ ∷ PlotOption → [EitherPlot] → EitherLayout+{-# INLINE plot_ #-}+plot_ opt ps | null ls = Right $ toLayout rs xAxisFnR+ | otherwise = Left $ toLayout ls xAxisFnL+ where+ toLayout x xAxisFn = layout_title .~ opt^.title+ $ layout_plots .~ x+ $ layout_x_axis .~ (+ laxis_title .~ opt^.xlab+ $ laxis_generate .~ xAxisFn+ $ laxis_style .~ xAxisStyle+ $ def+ )+ $ layout_y_axis .~ (+ laxis_title .~ opt^.ylab+ $ laxis_generate .~ yAxisFn+ $ laxis_style .~ yAxisStyle+ $ def+ )+ $ def++ (ls, rs) = partitionEithers ps+ xAxisFnL = autoIndexAxis (opt^.labels)+ xAxisFnR = if uncurry (>=) (opt^.xlim)+ then autoAxis+ else scaledAxis def (opt^.xlim)+ yAxisFn = if uncurry (>=) (opt^.ylim)+ then autoAxis+ else scaledAxis def (opt^.ylim)+ xAxisStyle = axis_grid_style .~ xGridStyle+ $ def+ yAxisStyle = axis_grid_style .~ yGridStyle+ $ def+ xGridStyle = case opt^.grid of+ 'b' → defaultGridLineStyle+ 'x' → defaultGridLineStyle+ _ → line_color .~ mkColor "black" 0 $ def++ yGridStyle = case opt^.grid of+ 'b' → defaultGridLineStyle+ 'y' → defaultGridLineStyle+ _ → line_color .~ mkColor "black" 0 $ def++plot ∷ PlotOption → [EitherPlot] → IO ()+plot opt ps = either f f (plot_ opt ps)+ where f x = renderableToWindow (toRenderable x) (opt^.width) (opt^.height)++plot' ∷ PlotOption → [EitherPlot] → String → IO ()+plot' opt ps flname = either f f (plot_ opt ps) flname >> return ()+ where f x = renderableToFile (fo_size .~ (opt^.width, opt^.height) $ def) (toRenderable x)
+ Graphics/Rendering/HPlot/Points.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax #-}+{-# LANGUAGE FlexibleContexts #-}++module Graphics.Rendering.HPlot.Points where++import qualified Data.Foldable as F+import Graphics.Rendering.Chart+import Control.Lens+import Data.Default+import Graphics.Rendering.HPlot.Types+import Graphics.Rendering.HPlot.Utils+import Data.Maybe++toPointStyle ∷ PointOption → PointStyle+toPointStyle opt = case () of+ _ | s `elem` ".●" → filledCircles r color+ | s `elem` "o○" → hollowCircles r thick color+ | s `elem` "x" → exes r thick color+ | s `elem` "+" → plusses r thick color+ | s `elem` "*" → stars r thick color+ | s `elem` "v▼" → filledPolygon r 3 True color+ | s `elem` "^▲" → filledPolygon r 3 False color+ | s `elem` "#■" → filledPolygon r 4 False color+ | s `elem` "◆" → filledPolygon r 4 True color+ | otherwise → filledCircles r color+ where+ s = opt^.shape+ r = opt^.radius+ color = mkColor (opt^.col) (opt^.opacity)+ thick = opt^.lwd++points ∷ F.Foldable f ⇒ PointOption → (Maybe (f Double), f Double) → EitherPlot+points opt (x, y) | isNothing x = Left $ mkPlot $ addIndexes y'+ | otherwise = Right $ mkPlot $ zip (F.toList $ fromJust x) y'+ where+ y' = F.toList y+ mkPlot x_y = toPlot $ plot_points_values .~ x_y+ $ plot_points_style .~ toPointStyle opt+ $ def
+ Graphics/Rendering/HPlot/Types.hs view
@@ -0,0 +1,224 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax, BangPatterns #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances #-}++module Graphics.Rendering.HPlot.Types (+ PlotOption+ , BarOption+ , LineOption+ , PointOption+ , HistOption+ , HeatMapOption++ -- | Lens+ , title+ , labels+ , xlab+ , ylab+ , xlim+ , ylim+ , width+ , height+ , grid+ , cols+ , opacity+ , align+ , space+ , style+ , legend+ , col+ , lty+ , lwd+ , radius+ , shape+ , breaks+ , labRow+ , labCol+ , palette++ , EitherPlot+ , EitherLayout+ ) where++import Graphics.Rendering.Chart+import Graphics.Rendering.HPlot.Utils+import Data.Colour+import Data.Colour.SRGB+import Control.Lens+import Data.Default++data PlotOption = PlotOption {+ _plotTitle ∷ String+ , _plotLabels ∷ [String]+ , _plotXlab ∷ String+ , _plotYlab ∷ String+ , _plotXlim ∷ (Double, Double)+ , _plotYlim ∷ (Double, Double)+ , _plotWidth ∷ Int+ , _plotHeight ∷ Int+ , _plotGrid ∷ Char+ } deriving (Show)++makeFields ''PlotOption++instance Default PlotOption where+ def = PlotOption {+ _plotTitle = []+ , _plotLabels = []+ , _plotXlab = []+ , _plotYlab = []+ , _plotXlim = (0, -1)+ , _plotYlim = (0, -1)+ , _plotWidth = 480+ , _plotHeight = 480+ , _plotGrid = 'b'+ }++data BarOption = BarOption {+ _barCols ∷ [String]+ , _barOpacity ∷ Double+ , _barAlign ∷ PlotBarsAlignment+ , _barSpace ∷ Double+ , _barStyle ∷ PlotBarsStyle+ , _barLegend ∷ [String]+ }++makeFields ''BarOption++instance Default BarOption where+ def = BarOption {+ _barOpacity = 1.0+ , _barCols = ["blue", "red", "green", "yellow", "cyan", "magenta"]+ , _barAlign = BarsCentered+ , _barSpace = 15+ , _barStyle = BarsClustered+ , _barLegend = []+ }++data LineOption = LineOption {+ _lineCol ∷ String+ , _lineOpacity ∷ Double+ , _lineLty ∷ Int+ , _lineLwd ∷ Double+ , lineJoin ∷ LineJoin+ }++makeFields ''LineOption++instance Default LineOption where+ def = LineOption {+ _lineOpacity = 1.0+ , _lineCol = "blue"+ , _lineLty = 1+ , _lineLwd = 1+ , lineJoin = LineJoinMiter+ }++data PointOption = PointOption {+ _pointRadius ∷ Double+ , _pointShape ∷ Char+ , _pointCol ∷ String+ , _pointOpacity ∷ Double+ , _pointLwd ∷ Double+ }++makeFields ''PointOption++instance Default PointOption where+ def = PointOption {+ _pointRadius = 3+ , _pointShape = '.'+ , _pointLwd = 1+ , _pointOpacity = 1.0+ , _pointCol = "blue"+ }++data HeatMapOption = HeatMapOption {+ _heatmapLabRow ∷ [String]+ , _heatmapLabCol ∷ [String]+ , _heatmapSpace ∷ Double+ , _heatmapTitle ∷ String+ , _heatmapXlab ∷ String+ , _heatmapYlab ∷ String+ , _heatmapWidth ∷ Int+ , _heatmapHeight ∷ Int+ , _heatmapPalette ∷ [Colour Double]+ , _heatmapOpacity ∷ Double+}++makeFields ''HeatMapOption++instance Default HeatMapOption where+ def = HeatMapOption {+ _heatmapLabRow = []+ , _heatmapLabCol = []+ , _heatmapSpace = 1+ , _heatmapTitle = ""+ , _heatmapXlab = ""+ , _heatmapYlab = ""+ , _heatmapWidth = 480+ , _heatmapHeight = 480+ , _heatmapPalette = warmCols+ , _heatmapOpacity = 1+ }++-- | print safe+warmCols ∷ [Colour Double]+warmCols = [+ sRGB24 255 255 178,+ sRGB24 254 217 118,+ sRGB24 254 178 76,+ sRGB24 253 141 60,+ sRGB24 240 59 32,+ sRGB24 189 0 38+ ]++coolCols ∷ [Colour Double]+coolCols = [+ sRGB24 255 255 204,+ sRGB24 199 233 180,+ sRGB24 127 205 187,+ sRGB24 65 182 196,+ sRGB24 44 127 184,+ sRGB24 37 52 148+ ]++type BreakRule = [Double] → Int++data HistOption = HistOption {+ _histTitle ∷ String+ , _histXlab ∷ String+ , _histYlab ∷ String+ , _histWidth ∷ Int+ , _histHeight ∷ Int+ , _histXlim ∷ (Double, Double)+ , _histYlim ∷ (Double, Double)+ , _histGrid ∷ Char+ , _histCol ∷ String+ , _histOpacity ∷ Double+ , _histBreaks ∷ BreakRule+ }++makeFields ''HistOption++instance Default HistOption where+ def = HistOption {+ _histTitle = []+ , _histXlab = []+ , _histYlab = "Frequency"+ , _histWidth = 480+ , _histHeight = 480+ , _histXlim = (0, -1)+ , _histYlim = (0, -1)+ , _histGrid = 'y'+ , _histCol = "blue"+ , _histOpacity = 1.0+ , _histBreaks = freedmanDiaconis+ }++type EitherPlot = Either (Plot PlotIndex Double) (Plot Double Double)++type EitherLayout = Either (Layout PlotIndex Double) (Layout Double Double)
+ Graphics/Rendering/HPlot/Utils.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE OverloadedStrings, UnicodeSyntax #-}++module Graphics.Rendering.HPlot.Utils (+ mkColor+ , freedmanDiaconis+ , squareRoot+ , riceRule+ , histogram_+ ) where++import qualified Data.Vector.Generic as G+import qualified Data.Vector.Generic.Mutable as GM+import Numeric.MathFunctions.Constants (m_epsilon)+import Data.Colour+import Data.Colour.Names+import Data.Maybe+import Data.List++-- Adapted from http://hackage.haskell.org/package/statistics-0.11.0.0/docs/Statistics-Quantile.html+quantile ∷ Int -- ^ /k/, the desired quantile.+ -> Int -- ^ /q/, the number of quantiles.+ -> [Double] -- ^ /x/, the sample data.+ -> Double+quantile k q x+ | any isNaN x = error "Sample contains NaNs"+ | n == 1 = head x+ | q < 2 = error "At least 2 quantiles is needed"+ | k < 0 || k >= q = error "Wrong quantile number"+ | otherwise = xj + g * (xj1 - xj)+ where+ j = floor idx+ idx = fromIntegral (n - 1) * fromIntegral k / fromIntegral q+ g = idx - fromIntegral j+ xj = sx !! j+ xj1 = sx !! (j+1)+ sx = sort x+ n = length x++histogram_ :: (Num b, RealFrac a, G.Vector v0 a, G.Vector v1 b) =>+ Int+ -- ^ Number of bins. This value must be positive. A zero+ -- or negative value will cause an error.+ -> a+ -- ^ Lower bound on interval range. Sample data less than+ -- this will cause an error.+ -> a+ -- ^ Upper bound on interval range. This value must not be+ -- less than the lower bound. Sample data that falls above+ -- the upper bound will cause an error.+ -> v0 a+ -- ^ Sample data.+ -> v1 b+histogram_ numBins lo hi xs0 = G.create (GM.replicate numBins 0 >>= bin xs0)+ where+ bin xs bins = go 0+ where+ go i | i >= len = return bins+ | otherwise = do+ let x = xs `G.unsafeIndex` i+ b = truncate $ (x - lo) / d+ GM.write bins b . (+1) =<< GM.read bins b+ go (i+1)+ len = G.length xs+ d = ((hi - lo) * (1 + realToFrac m_epsilon)) / fromIntegral numBins++mkColor ∷ String → Double → AlphaColour Double+mkColor c = withOpacity (fromMaybe blue $ readColourName c)++freedmanDiaconis, squareRoot, riceRule ∷ [Double] → Int+freedmanDiaconis xs = round ((maximum xs - minimum xs) / binSzie)+ where+ binSzie = 2 * iqr xs * n**(-1/3)+ n = fromIntegral $ length xs+ iqr x = let quartile3 = quantile 3 4 x+ quartile1 = quantile 1 4 x+ in quartile3 - quartile1++squareRoot = round . (sqrt ∷ Double → Double) . fromIntegral . length++riceRule xs = ceiling (2*(fromIntegral $ length xs ∷ Double)**(1/3))
+ LICENSE view
@@ -0,0 +1,339 @@+GNU GENERAL PUBLIC LICENSE+ Version 2, June 1991++ Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++ Preamble++ The licenses for most software are designed to take away your+freedom to share and change it. By contrast, the GNU General Public+License is intended to guarantee your freedom to share and change free+software--to make sure the software is free for all its users. This+General Public License applies to most of the Free Software+Foundation's software and to any other program whose authors commit to+using it. (Some other Free Software Foundation software is covered by+the GNU Lesser General Public License instead.) You can apply it to+your programs, too.++ When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+this service if you wish), that you receive source code or can get it+if you want it, that you can change the software or use pieces of it+in new free programs; and that you know you can do these things.++ To protect your rights, we need to make restrictions that forbid+anyone to deny you these rights or to ask you to surrender the rights.+These restrictions translate to certain responsibilities for you if you+distribute copies of the software, or if you modify it.++ For example, if you distribute copies of such a program, whether+gratis or for a fee, you must give the recipients all the rights that+you have. You must make sure that they, too, receive or can get the+source code. And you must show them these terms so they know their+rights.++ We protect your rights with two steps: (1) copyright the software, and+(2) offer you this license which gives you legal permission to copy,+distribute and/or modify the software.++ Also, for each author's protection and ours, we want to make certain+that everyone understands that there is no warranty for this free+software. If the software is modified by someone else and passed on, we+want its recipients to know that what they have is not the original, so+that any problems introduced by others will not reflect on the original+authors' reputations.++ Finally, any free program is threatened constantly by software+patents. We wish to avoid the danger that redistributors of a free+program will individually obtain patent licenses, in effect making the+program proprietary. To prevent this, we have made it clear that any+patent must be licensed for everyone's free use or not licensed at all.++ The precise terms and conditions for copying, distribution and+modification follow.++ GNU GENERAL PUBLIC LICENSE+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION++ 0. This License applies to any program or other work which contains+a notice placed by the copyright holder saying it may be distributed+under the terms of this General Public License. The "Program", below,+refers to any such program or work, and a "work based on the Program"+means either the Program or any derivative work under copyright law:+that is to say, a work containing the Program or a portion of it,+either verbatim or with modifications and/or translated into another+language. (Hereinafter, translation is included without limitation in+the term "modification".) Each licensee is addressed as "you".++Activities other than copying, distribution and modification are not+covered by this License; they are outside its scope. The act of+running the Program is not restricted, and the output from the Program+is covered only if its contents constitute a work based on the+Program (independent of having been made by running the Program).+Whether that is true depends on what the Program does.++ 1. You may copy and distribute verbatim copies of the Program's+source code as you receive it, in any medium, provided that you+conspicuously and appropriately publish on each copy an appropriate+copyright notice and disclaimer of warranty; keep intact all the+notices that refer to this License and to the absence of any warranty;+and give any other recipients of the Program a copy of this License+along with the Program.++You may charge a fee for the physical act of transferring a copy, and+you may at your option offer warranty protection in exchange for a fee.++ 2. You may modify your copy or copies of the Program or any portion+of it, thus forming a work based on the Program, and copy and+distribute such modifications or work under the terms of Section 1+above, provided that you also meet all of these conditions:++ a) You must cause the modified files to carry prominent notices+ stating that you changed the files and the date of any change.++ b) You must cause any work that you distribute or publish, that in+ whole or in part contains or is derived from the Program or any+ part thereof, to be licensed as a whole at no charge to all third+ parties under the terms of this License.++ c) If the modified program normally reads commands interactively+ when run, you must cause it, when started running for such+ interactive use in the most ordinary way, to print or display an+ announcement including an appropriate copyright notice and a+ notice that there is no warranty (or else, saying that you provide+ a warranty) and that users may redistribute the program under+ these conditions, and telling the user how to view a copy of this+ License. (Exception: if the Program itself is interactive but+ does not normally print such an announcement, your work based on+ the Program is not required to print an announcement.)++These requirements apply to the modified work as a whole. If+identifiable sections of that work are not derived from the Program,+and can be reasonably considered independent and separate works in+themselves, then this License, and its terms, do not apply to those+sections when you distribute them as separate works. But when you+distribute the same sections as part of a whole which is a work based+on the Program, the distribution of the whole must be on the terms of+this License, whose permissions for other licensees extend to the+entire whole, and thus to each and every part regardless of who wrote it.++Thus, it is not the intent of this section to claim rights or contest+your rights to work written entirely by you; rather, the intent is to+exercise the right to control the distribution of derivative or+collective works based on the Program.++In addition, mere aggregation of another work not based on the Program+with the Program (or with a work based on the Program) on a volume of+a storage or distribution medium does not bring the other work under+the scope of this License.++ 3. You may copy and distribute the Program (or a work based on it,+under Section 2) in object code or executable form under the terms of+Sections 1 and 2 above provided that you also do one of the following:++ a) Accompany it with the complete corresponding machine-readable+ source code, which must be distributed under the terms of Sections+ 1 and 2 above on a medium customarily used for software interchange; or,++ b) Accompany it with a written offer, valid for at least three+ years, to give any third party, for a charge no more than your+ cost of physically performing source distribution, a complete+ machine-readable copy of the corresponding source code, to be+ distributed under the terms of Sections 1 and 2 above on a medium+ customarily used for software interchange; or,++ c) Accompany it with the information you received as to the offer+ to distribute corresponding source code. (This alternative is+ allowed only for noncommercial distribution and only if you+ received the program in object code or executable form with such+ an offer, in accord with Subsection b above.)++The source code for a work means the preferred form of the work for+making modifications to it. For an executable work, complete source+code means all the source code for all modules it contains, plus any+associated interface definition files, plus the scripts used to+control compilation and installation of the executable. However, as a+special exception, the source code distributed need not include+anything that is normally distributed (in either source or binary+form) with the major components (compiler, kernel, and so on) of the+operating system on which the executable runs, unless that component+itself accompanies the executable.++If distribution of executable or object code is made by offering+access to copy from a designated place, then offering equivalent+access to copy the source code from the same place counts as+distribution of the source code, even though third parties are not+compelled to copy the source along with the object code.++ 4. You may not copy, modify, sublicense, or distribute the Program+except as expressly provided under this License. Any attempt+otherwise to copy, modify, sublicense or distribute the Program is+void, and will automatically terminate your rights under this License.+However, parties who have received copies, or rights, from you under+this License will not have their licenses terminated so long as such+parties remain in full compliance.++ 5. You are not required to accept this License, since you have not+signed it. However, nothing else grants you permission to modify or+distribute the Program or its derivative works. These actions are+prohibited by law if you do not accept this License. Therefore, by+modifying or distributing the Program (or any work based on the+Program), you indicate your acceptance of this License to do so, and+all its terms and conditions for copying, distributing or modifying+the Program or works based on it.++ 6. Each time you redistribute the Program (or any work based on the+Program), the recipient automatically receives a license from the+original licensor to copy, distribute or modify the Program subject to+these terms and conditions. You may not impose any further+restrictions on the recipients' exercise of the rights granted herein.+You are not responsible for enforcing compliance by third parties to+this License.++ 7. If, as a consequence of a court judgment or allegation of patent+infringement or for any other reason (not limited to patent issues),+conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License. If you cannot+distribute so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you+may not distribute the Program at all. For example, if a patent+license would not permit royalty-free redistribution of the Program by+all those who receive copies directly or indirectly through you, then+the only way you could satisfy both it and this License would be to+refrain entirely from distribution of the Program.++If any portion of this section is held invalid or unenforceable under+any particular circumstance, the balance of the section is intended to+apply and the section as a whole is intended to apply in other+circumstances.++It is not the purpose of this section to induce you to infringe any+patents or other property right claims or to contest validity of any+such claims; this section has the sole purpose of protecting the+integrity of the free software distribution system, which is+implemented by public license practices. Many people have made+generous contributions to the wide range of software distributed+through that system in reliance on consistent application of that+system; it is up to the author/donor to decide if he or she is willing+to distribute software through any other system and a licensee cannot+impose that choice.++This section is intended to make thoroughly clear what is believed to+be a consequence of the rest of this License.++ 8. If the distribution and/or use of the Program is restricted in+certain countries either by patents or by copyrighted interfaces, the+original copyright holder who places the Program under this License+may add an explicit geographical distribution limitation excluding+those countries, so that distribution is permitted only in or among+countries not thus excluded. In such case, this License incorporates+the limitation as if written in the body of this License.++ 9. The Free Software Foundation may publish revised and/or new versions+of the General Public License from time to time. Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++Each version is given a distinguishing version number. If the Program+specifies a version number of this License which applies to it and "any+later version", you have the option of following the terms and conditions+either of that version or of any later version published by the Free+Software Foundation. If the Program does not specify a version number of+this License, you may choose any version ever published by the Free Software+Foundation.++ 10. If you wish to incorporate parts of the Program into other free+programs whose distribution conditions are different, write to the author+to ask for permission. For software which is copyrighted by the Free+Software Foundation, write to the Free Software Foundation; we sometimes+make exceptions for this. Our decision will be guided by the two goals+of preserving the free status of all derivatives of our free software and+of promoting the sharing and reuse of software generally.++ NO WARRANTY++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,+REPAIR OR CORRECTION.++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE+POSSIBILITY OF SUCH DAMAGES.++ END OF TERMS AND CONDITIONS++ How to Apply These Terms to Your New Programs++ If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++ To do so, attach the following notices to the program. It is safest+to attach them to the start of each source file to most effectively+convey the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++ {description}+ Copyright (C) {year} {fullname}++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License along+ with this program; if not, write to the Free Software Foundation, Inc.,+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.++Also add information on how to contact you by electronic and paper mail.++If the program is interactive, make it output a short notice like this+when it starts in an interactive mode:++ Gnomovision version 69, Copyright (C) year name of author+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+ This is free software, and you are welcome to redistribute it+ under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License. Of course, the commands you use may+be called something other than `show w' and `show c'; they could even be+mouse-clicks or menu items--whatever suits your program.++You should also get your employer (if you work as a programmer) or your+school, if any, to sign a "copyright disclaimer" for the program, if+necessary. Here is a sample; alter the names:++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program+ `Gnomovision' (which makes passes at compilers) written by James Hacker.++ {signature of Ty Coon}, 1 April 1989+ Ty Coon, President of Vice++This General Public License does not permit incorporating your program into+proprietary programs. If your program is a subroutine library, you may+consider it more useful to permit linking proprietary applications with the+library. If this is what you want to do, use the GNU Lesser General+Public License instead of this License.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ haskell-plot.cabal view
@@ -0,0 +1,45 @@+-- Initial haskell-plot.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: haskell-plot+version: 0.1.0.0+synopsis: A library for generating 2D plots painlessly.+description: Greatly simplify the API of Chart (<http://hackage.haskell.org/package/Chart>).+homepage: https://github.com/kaizhang/haskell-plot+license: GPL+license-file: LICENSE+author: Kai Zhang <kai@kzhang.org>+maintainer: Kai Zhang <kai@kzhang.org>+-- copyright: +category: Graphics+build-type: Simple+cabal-version: >=1.8+source-repository head+ type: git+ location: https://github.com/kaizhang/haskell-plot++library+ exposed-modules: + Graphics.Rendering.HPlot,+ Graphics.Rendering.HPlot.Types,+ Graphics.Rendering.HPlot.Plot,+ Graphics.Rendering.HPlot.Hist,+ Graphics.Rendering.HPlot.Points,+ Graphics.Rendering.HPlot.Bars,+ Graphics.Rendering.HPlot.Lines,+ Graphics.Rendering.HPlot.Utils,+ Graphics.Rendering.HPlot.HeatMap++ other-modules: + Graphics.Rendering.HPlot.HeatMap.Internal++ build-depends:+ base >=4 && < 5+ , lens >= 3.10+ , data-default >= 0.5+ , colour >= 2.3+ , vector >= 0.10+ , math-functions >= 0.1+ , Chart >= 1.2+ , Chart-cairo >= 1.2+ , Chart-gtk >= 1.2