Copyright | Marco Zocca 2017 |
---|---|
License | BSD3 |
Maintainer | Marco Zocca <zocca marco gmail> |
Safe Haskell | None |
Language | Haskell2010 |
`plot-light` provides functionality for rendering vector graphics in SVG format. It is geared in particular towards scientific plotting, and it is termed "light" because it only requires few native Haskell dependencies.
It builds upon `blaze-svg` by adding type-safe combinators, geometry primitives and related functions.
Usage
To use this project you just need to import this module qualified (to avoid name clashes with any other modules you might have loaded on the side), for example as follows :
import Graphics.Rendering.Plot.Light as P
If you wish to try out the examples in this page, you will need to have renderSvg
in scope as well:
import Text.Blaze.Svg.Renderer.String (renderSvg)
- rectCentered :: Point Double -> Double -> Double -> Colour Double -> Svg
- line :: Point Double -> Point Double -> Double -> Colour Double -> Svg
- axis :: (Functor t, Foldable t) => Axis -> Double -> Double -> Colour Double -> Double -> Point Double -> t (Point Double) -> Svg
- text :: (Show a, Show a1, ToValue a2) => a1 -> Colour Double -> Text -> V2 a2 -> Point a -> Svg
- polyline :: (Show a1, Show a) => [(a1, a)] -> Double -> Colour Double -> Svg
- data FigureData a = FigData {}
- data Point a = Point {}
- data LabeledPoint l a = LabeledPoint {}
- data Axis
- mkFigureData :: Num a => Point a -> a -> a -> FigureData a
- svgHeader :: FigureData Int -> Svg -> Svg
- data V2 a = V2 a a
- data Mat2 a = Mat2 a a a a
- data DiagMat2 a = DMat2 a a
- diagMat2 :: Num a => a -> a -> Mat2 a
- origin :: Num a => Point a
- e1 :: Num a => V2 a
- e2 :: Num a => V2 a
- norm2 :: (Hermitian v, Floating n, n ~ InnerProduct v) => v -> n
- normalize2 :: (InnerProduct v ~ Scalar v, Floating (Scalar v), Hermitian v) => v -> v
- mkV2fromEndpoints :: Num a => Point a -> Point a -> V2 a
- v2fromPoint :: Num a => Point a -> V2 a
- movePoint :: Num a => V2 a -> Point a -> Point a
- moveLabeledPointV2 :: Num a => V2 a -> LabeledPoint l a -> LabeledPoint l a
- fromUnitSquare :: Num a => Frame a -> Point a -> Point a
- toUnitSquare :: (Fractional a, MatrixGroup (Mat2 a) (V2 a)) => Frame a -> Point a -> Point a
- class AdditiveGroup v where
- class AdditiveGroup v => VectorSpace v where
- class VectorSpace v => Hermitian v where
- type InnerProduct v :: *
- class Hermitian v => LinearMap m v where
- class MultiplicativeSemigroup m where
- class LinearMap m v => MatrixGroup m v where
Graphical elements
A filled rectangle
:: Point Double | First point |
-> Point Double | Second point |
-> Double | Stroke width |
-> Colour Double | Stroke colour |
-> Svg |
Line segment between two Point
s
> putStrLn $ renderSvg (line 0 0 1 1 0.1 C.blueviolet) <line x1="0.0" y1="0.0" x2="1.0" y2="1.0" stroke="#8a2be2" stroke-width="0.1" />
:: (Functor t, Foldable t) | |
=> Axis | |
-> Double | Length |
-> Double | Stroke width |
-> Colour Double | Stroke colour |
-> Double | Tick length fraction (w.r.t axis length) |
-> Point Double | Axis center coordinate |
-> t (Point Double) | Tick center coordinates |
-> Svg |
An axis with tickmarks
> putStrLn $ renderSvg $ axis X 200 2 C.red 0.05 (Point 150 10) [Point 50 1, Point 60 1, Point 70 1] <line x1="50.0" y1="10.0" x2="250.0" y2="10.0" stroke="#ff0000" stroke-width="2.0" /><line x1="50.0" y1="5.0" x2="50.0" y2="15.0" stroke="#ff0000" stroke-width="2.0" /><line x1="60.0" y1="5.0" x2="60.0" y2="15.0" stroke="#ff0000" stroke-width="2.0" /><line x1="70.0" y1="5.0" x2="70.0" y2="15.0" stroke="#ff0000" stroke-width="2.0" />
:: (Show a, Show a1, ToValue a2) | |
=> a1 | Rotation angle |
-> Colour Double | Font colour |
-> Text | Text |
-> V2 a2 | Displacement |
-> Point a | Initial center position of the text box |
-> Svg |
text
renders text onto the SVG canvas. It is also possible to rotate and move the text, however the order of these modifiers matters.
NB1: The Point
parameter p
determines the initial position of the bottom-left corner of the text box. If a nonzero rotation is applied, the whole text box will move on a circle of radius || x^2 + y^2 || centered at p
.
NB2: the rotate
and translate
attributes apply to the center of the visible text instead.
> putStrLn $ renderSvg $ text (-45) C.red "hullo!" (V2 (-30) 0) (Point 0 20) <text x="-30" y="0" transform="translate(0 20)rotate(-45)" fill="#ff0000">hullo!</text>
Polyline (piecewise straight line)
> putStrLn $ renderSvg (polyline [(1,1), (2,1), (2,2), (3,4)] 0.1 C.red) <polyline points="1,1 2,1 2,2 3,4" fill="none" stroke="#ff0000" stroke-width="0.1" />
Types
data FigureData a Source #
Eq a => Eq (FigureData a) Source # | |
Show a => Show (FigureData a) Source # | |
A Point
defines a point in R2
data LabeledPoint l a Source #
A LabeledPoint
carries a "label" (i.e. any additional information such as a text tag, or any other data structure), in addition to position information. Data points on a plot are LabeledPoint
s.
mkFigureData :: Num a => Point a -> a -> a -> FigureData a Source #
Create a FigureData
structure from the top-left corner point and its side lengths
svgHeader :: FigureData Int -> Svg -> Svg Source #
Create the SVG header from FigureData
Geometry
Vectors
V2 is a vector in R^2
V2 a a |
Eq a => Eq (V2 a) Source # | |
Show a => Show (V2 a) Source # | |
Num a => Monoid (V2 a) Source # | Vectors form a monoid w.r.t. vector addition |
Num a => Hermitian (V2 a) Source # | |
Num a => VectorSpace (V2 a) Source # | |
Num a => AdditiveGroup (V2 a) Source # | Vectors form an additive group |
Fractional a => MatrixGroup (DiagMat2 a) (V2 a) Source # | Diagonal matrices can always be inverted |
Num a => LinearMap (DiagMat2 a) (V2 a) Source # | |
Num a => LinearMap (Mat2 a) (V2 a) Source # | |
type InnerProduct (V2 a) Source # | |
type Scalar (V2 a) Source # | |
Matrices
A Mat2 can be seen as a linear operator that acts on points in the plane
Mat2 a a a a |
Diagonal matrices in R2 behave as scaling transformations
DMat2 a a |
Primitive elements
Vector operations
normalize2 :: (InnerProduct v ~ Scalar v, Floating (Scalar v), Hermitian v) => v -> v Source #
Normalize a V2 w.r.t. its Euclidean norm
Vector construction
mkV2fromEndpoints :: Num a => Point a -> Point a -> V2 a Source #
Create a V2 v
from two endpoints p1, p2. That is v
can be seen as pointing from p1
to p2
v2fromPoint :: Num a => Point a -> V2 a Source #
Build a V2 from a Point
p (i.e. assuming the V2 points from the origin (0,0) to p)
Operations on points
moveLabeledPointV2 :: Num a => V2 a -> LabeledPoint l a -> LabeledPoint l a Source #
Move a LabeledPoint
along a vector
fromUnitSquare :: Num a => Frame a -> Point a -> Point a Source #
The vector translation from a Point
p
contained in the unit square onto a Frame
NB: we do not check that p
is actually contained in [0,1] x [0,1], This has to be supplied correctly by the user
toUnitSquare :: (Fractional a, MatrixGroup (Mat2 a) (V2 a)) => Frame a -> Point a -> Point a Source #
The vector translation from a Point
contained in a Frame
onto the unit square
NB: we do not check that p
is actually contained within the frame. This has to be supplied correctly by the user
Typeclasses
class AdditiveGroup v where Source #
Additive group :
v ^+^ zero == zero ^+^ v == v
v ^-^ v == zero
Identity element
Group action ("sum")
Inverse group action ("subtraction")
Num a => AdditiveGroup (V2 a) Source # | Vectors form an additive group |
class AdditiveGroup v => VectorSpace v where Source #
Vector space : multiplication by a scalar quantity
Num a => VectorSpace (V2 a) Source # | |
class VectorSpace v => Hermitian v where Source #
Hermitian space : inner product
type InnerProduct v :: * Source #
(<.>) :: v -> v -> InnerProduct v Source #
Inner product
class Hermitian v => LinearMap m v where Source #
Linear maps, i.e. linear transformations of vectors
class MultiplicativeSemigroup m where Source #
Multiplicative matrix semigroup ("multiplying" two matrices together)
Num a => MultiplicativeSemigroup (DiagMat2 a) Source # | |
Num a => MultiplicativeSemigroup (Mat2 a) Source # | |
class LinearMap m v => MatrixGroup m v where Source #
The class of invertible linear transformations
Fractional a => MatrixGroup (DiagMat2 a) (V2 a) Source # | Diagonal matrices can always be inverted |