module Graphics.Matplotlib
( module Graphics.Matplotlib
, Matplotlib(), Option(),(@@), (%), o1, o2, (##), (#), mp, def, readData)
where
import Data.List
import Data.Aeson
import Graphics.Matplotlib.Internal
onscreen :: Matplotlib -> IO (Either String String)
onscreen m = withMplot m (\str -> python $ pyIncludes ++ str ++ pyDetach ++ pyOnscreen)
code :: Matplotlib -> IO String
code m = withMplot m (\str -> return $ unlines $ pyIncludes ++ str ++ pyDetach ++ pyOnscreen)
figure :: [Char] -> Matplotlib -> IO (Either String String)
figure filename m = withMplot m (\str -> python $ pyIncludes ++ str ++ pyFigure filename)
xacorr xs ys opts = readData (xs, ys)
% addSubplot 2 1 1
% xcorr xs ys @@ opts
% grid True
% axhline 0 @@ [o1 "0", o2 "color" "'black'", o2 "lw" "2"]
% addSubplot 2 1 2 @@ [o2 "sharex" "ax"]
% acorr xs @@ opts
% grid True
% axhline 0 @@ [o2 "color" "'black'", o2 "lw" "2"]
histogram :: (MplotValue val, ToJSON t) => t -> val -> Matplotlib
histogram values bins = readData [values] % dataHistogram 0 bins
histogram2D x y = readData [x,y] %
mp # "plot.hist2d(data[0], data[1]" ## ")"
scatter :: (ToJSON t1, ToJSON t) => t1 -> t -> Matplotlib
scatter x y = plot x y `def` [o1 "'.'"]
line :: (ToJSON t1, ToJSON t) => t1 -> t -> Matplotlib
line x y = plot x y `def` [o1 "'-'"]
errorbar xs ys errs = readData (xs, ys, errs)
% mp # "ax.errorbar(data[0], data[1], yerr=data[2]" ## ")"
lineF :: (ToJSON a, ToJSON b) => (a -> b) -> [a] -> Matplotlib
lineF f l = plot l (map f l) `def` [o1 "'-'"]
boxplot l = readData l
% mp # "ax.boxplot(data" ## ")"
contourF :: (ToJSON val, MplotValue val, Ord val) => (Double -> Double -> val) -> Double -> Double -> Double -> Double -> Double -> Matplotlib
contourF f xStart xEnd yStart yEnd steps = contour xs ys zs
where xs = mapLinear (\x -> (mapLinear (\_ -> x) yStart yEnd steps)) xStart xEnd steps
ys = mapLinear (\_ -> (mapLinear (\y -> y) yStart yEnd steps)) xStart xEnd steps
zs = mapLinear (\x -> (mapLinear (\y -> f x y) yStart yEnd steps)) xStart xEnd steps
projectionsF :: (ToJSON val, MplotValue val, Ord val) => (Double -> Double -> val) -> Double -> Double -> Double -> Double -> Double -> Matplotlib
projectionsF f xStart xEnd yStart yEnd steps = projections xs ys zs
where xs = mapLinear (\x -> (mapLinear (\_ -> x) yStart yEnd steps)) xStart xEnd steps
ys = mapLinear (\_ -> (mapLinear (\y -> y) yStart yEnd steps)) xStart xEnd steps
zs = mapLinear (\x -> (mapLinear (\y -> f x y) yStart yEnd steps)) xStart xEnd steps
plotInterpolated :: (MplotValue val, ToJSON t, ToJSON t1) => t1 -> t -> val -> Matplotlib
plotInterpolated x y n =
readData (x, y)
% interpolate 0 1 n
% dataPlot 0 1 `def` [o1 "-"]
plotMapLinear :: ToJSON b => (Double -> b) -> Double -> Double -> Double -> Matplotlib
plotMapLinear f s e n = line xs ys
where xs = mapLinear (\x -> x) s e n
ys = mapLinear (\x -> f x) s e n
line1 :: (Foldable t, ToJSON (t a)) => t a -> Matplotlib
line1 y = line [0..length y] y
matShow :: ToJSON a => a -> Matplotlib
matShow d = readData d
% (mp # "plot.matshow(data" ## ")")
pcolor :: ToJSON a => a -> Matplotlib
pcolor d = readData d
% (mp # "plot.pcolor(np.array(data)" ## ")")
density :: [Double] -> Maybe (Double, Double) -> Matplotlib
density l maybeStartEnd =
densityBandwidth l (((4 * (variance ** 5)) / (fromIntegral $ 3 * length l)) ** (1 / 5) / 3) maybeStartEnd
where mean = foldl' (+) 0 l / (fromIntegral $ length l)
variance = foldl' (+) 0 (map (\x -> sqr (x mean)) l) / (fromIntegral $ length l)
sqr x = x * x
setTeX :: Bool -> Matplotlib
setTeX b = mp # "matplotlib.rcParams['text.usetex'] = " # b
setUnicode :: Bool -> Matplotlib
setUnicode b = mp # "matplotlib.rcParams['text.latex.unicode'] = " # b
dataPlot :: (MplotValue val, MplotValue val1) => val1 -> val -> Matplotlib
dataPlot a b = mp # "p = plot.plot(data[" # a # "], data[" # b # "]" ## ")"
plot :: (ToJSON t, ToJSON t1) => t1 -> t -> Matplotlib
plot x y = readData (x, y) % dataPlot 0 1
grid :: Bool -> Matplotlib
grid t = mp # "plot.gca().grid(" # t # ")"
dateLine :: (ToJSON t1, ToJSON t2) => t1 -> t2 -> String -> (Int, Int, Int) -> Matplotlib
dateLine x y xunit (yearStart, monthStart, dayStart) =
readData (x, y)
% mp # "data[0] = [datetime.timedelta("#xunit#"=i) + datetime.datetime("#yearStart#","#monthStart#","#dayStart#") for i in data[0]]"
% dataPlot 0 1 `def` [o1 "-"]
% mp # "ax.xaxis.set_major_formatter(DateFormatter('%B'))"
% mp # "ax.xaxis.set_minor_locator(WeekdayLocator(byweekday=6))"
xLabel :: MplotValue val => val -> Matplotlib
xLabel label = mp # "plot.xlabel(r'" # label # "'" ## ")"
yLabel :: MplotValue val => val -> Matplotlib
yLabel label = mp # "plot.ylabel(r'" # label # "'" ## ")"
zLabel :: MplotValue val => val -> Matplotlib
zLabel label = mp # "plot.zlabel(r'" # label # "'" ## ")"
dataHistogram :: (MplotValue val1, MplotValue val) => val1 -> val -> Matplotlib
dataHistogram a bins = mp # "plot.hist(data[" # a # "]," # bins ## ")"
dataScatter :: (MplotValue val1, MplotValue val) => val1 -> val -> Matplotlib
dataScatter a b = dataPlot a b `def` [o1 "'.'"]
dataLine :: (MplotValue val1, MplotValue val) => val1 -> val -> Matplotlib
dataLine a b = dataPlot a b `def` [o1 "'-'"]
contour xs ys zs =
readData (xs, ys, zs)
% axis3DProjection
% surface 0 1 2
% contourRaw 0 1 2 (maximum2 xs) (maximum2 ys) (minimum2 zs)
% axis3DLabels xs ys zs
projections xs ys zs =
readData (xs, ys, zs)
% axis3DProjection
% contourRaw 0 1 2 (maximum2 xs) (maximum2 ys) (minimum2 zs)
% axis3DLabels xs ys zs
axis3DProjection :: Matplotlib
axis3DProjection = mp # "ax = plot.gca(projection='3d')"
wireframe :: (MplotValue val2, MplotValue val1, MplotValue val) => val2 -> val1 -> val -> Matplotlib
wireframe a b c = mp # "ax.plot_wireframe(np.array(data[" # a # "]), np.array(data[" # b # "]), np.array(data[" # c # "]), rstride=1, cstride=1)"
surface :: (MplotValue val2, MplotValue val1, MplotValue val) => val2 -> val1 -> val -> Matplotlib
surface a b c = mp # "ax.plot_surface(np.array(data[" # a # "]), np.array(data[" # b # "]), np.array(data[" # c # "]), rstride=1, cstride=1, cmap=cm.Blues, alpha=0.3)"
contourRaw :: (MplotValue val1, MplotValue val2, MplotValue val5,
MplotValue val4, MplotValue val3, MplotValue val) =>
val5 -> val4 -> val3 -> val2 -> val1 -> val -> Matplotlib
contourRaw a b c maxA maxB minC =
mp # "ax.contour(data[" # a # "], data[" # b # "], data[" # c # "], zdir='z', offset=" # minC # ")"
% mp # "ax.contour(data[" # a # "], data[" # b # "], data[" # c # "], zdir='x', offset=-" # maxA # ")"
% mp # "ax.contour(data[" # a # "], data[" # b # "], data[" # c # "], zdir='y', offset=" # maxB #")"
minimum2 :: (Ord (t a), Ord a, Foldable t1, Foldable t) => t1 (t a) -> a
minimum2 l = minimum $ minimum l
maximum2 :: (Ord (t a), Ord a, Foldable t1, Foldable t) => t1 (t a) -> a
maximum2 l = maximum $ maximum l
axis3DLabels xs ys zs =
mp # "ax.set_xlabel('X')"
% mp # "ax.set_xlim3d(" # minimum2 xs # ", " # maximum2 xs # ")"
% mp # "ax.set_ylabel('Y')"
% mp # "ax.set_ylim3d(" # minimum2 ys # ", " # maximum2 ys # ")"
% mp # "ax.set_zlabel('Z')"
% mp # "ax.set_zlim3d(" # minimum2 zs # ", " # maximum2 zs # ")"
subplotDataBar a width offset opts =
mp # "ax.bar(np.arange(len(data[" # a # "]))+" # offset # ", data[" # a # "], " # width ## ")" @@ opts
addSubplot r c f = mp # "ax = plot.gcf().add_subplot(" # r # c # f ## ")"
getSubplot r c f = mp # "ax = plot.subplot(" # r # "," # c # "," # f ## ")"
barDefaultWidth nr = 1.0 / (fromIntegral nr + 1)
subplotBarsLabelled valuesList labels optsList =
subplotBars valuesList optsList
% axisXTickSpacing (length $ head $ valuesList) (1.0 barDefaultWidth (length valuesList) / 2.0)
% axisXTickLabels labels
subplotBars valuesList optsList =
readData valuesList
% addSubplot 1 1 1
% (let width = barDefaultWidth (length valuesList) in
foldl1 (%) (zipWith3 (\_ opts i -> subplotDataBar i width (width * i) opts) valuesList optsList [0..]))
title :: MplotValue val => val -> Matplotlib
title s = mp # "plot.title(r'" # s # "'" ## ")"
axisXTickSpacing :: (MplotValue val1, MplotValue val) => val1 -> val -> Matplotlib
axisXTickSpacing nr width = mp # "ax.set_xticks(np.arange(" # nr # ")+" # width ## ")"
axisXTickLabels :: MplotValue val => val -> Matplotlib
axisXTickLabels labels = mp # "ax.set_xticklabels( (" # labels # ") " ## " )"
interpolate :: (MplotValue val, MplotValue val2, MplotValue val1) => val2 -> val1 -> val -> Matplotlib
interpolate a b n =
(mp # "data[" # b # "] = mlab.stineman_interp(np.linspace(data[" # a # "][0],data[" # a # "][-1]," # n # "),data[" # a # "],data[" # b # "],None)")
% (mp # "data[" # a # "] = np.linspace(data[" # a # "][0],data[" # a # "][-1]," # n # ")")
squareAxes :: Matplotlib
squareAxes = mp # "plot.axes().set_aspect('equal')"
roateAxesLabels :: MplotValue val => val -> Matplotlib
roateAxesLabels degrees = mp # "labels = plot.axes().get_xticklabels()"
% mp # "for label in labels:"
% mp # " label.set_rotation("#degrees#")"
verticalAxes :: Matplotlib
verticalAxes = mp # "labels = plot.axes().get_xticklabels()"
% mp # "for label in labels:"
% mp # " label.set_rotation('vertical')"
logX :: Matplotlib
logX = mp # "plot.axes().set_xscale('log')"
logY :: Matplotlib
logY = mp # "plot.axes().set_yscale('log')"
xlim :: (MplotValue val1, MplotValue val) => val1 -> val -> Matplotlib
xlim l u = mp # "plot.xlim([" # l # "," # u # "])"
ylim :: (MplotValue val1, MplotValue val) => val1 -> val -> Matplotlib
ylim l u = mp # "plot.ylim([" # l # "," # u # "])"
densityBandwidth :: [Double] -> Double -> Maybe (Double, Double) -> Matplotlib
densityBandwidth l h maybeStartEnd =
plotMapLinear f (case maybeStartEnd of
Nothing -> minimum l
(Just (start, _)) -> start)
(case maybeStartEnd of
Nothing -> maximum l
(Just (_, end)) -> end)
100
where f x = sum (map (\xi -> gaussianPdf x xi h) l) / ((fromIntegral $ length l) * h)
gaussianPdf x mu sigma = exp ( sqr (x mu) / (2 * sigma)) / sqrt (2 * pi * sigma)
sqr x = x * x
axhline y = mp # "ax.axhline(" # y ## ")"
xcorr x y = readData (x, y) % mp # "ax.xcorr(data[0], data[1]" ## ")"
acorr x = readData x % mp # "ax.acorr(data" ## ")"
text x y str = mp # "ax.text(" # x # "," # y # "," # "'" # str # "'" ## ")"
legend = mp # "plot.legend(" ## ")"
colorbar = mp # "plot.colorbar(" ## ")"
subplots = mp # "fig, axes = plot.subplots(" ## ")"
setSubplot s = mp # "ax = axes[" # s # "]"