plots 0.1.0.2 → 0.1.1.0
raw patch · 21 files changed
+305/−118 lines, 21 filessetup-changed
Files
- README.md +10/−1
- Setup.hs +0/−2
- diagrams/src_Plots_Types_Scatter_bubbleExample.svg +1/−0
- plots.cabal +3/−3
- src/Diagrams/Coordinates/Polar.hs +2/−2
- src/Plots.hs +5/−5
- src/Plots/Axis.hs +6/−6
- src/Plots/Axis/ColourBar.hs +19/−2
- src/Plots/Axis/Grid.hs +5/−5
- src/Plots/Axis/Labels.hs +32/−10
- src/Plots/Axis/Render.hs +3/−3
- src/Plots/Axis/Title.hs +16/−1
- src/Plots/Legend.hs +11/−5
- src/Plots/Style.hs +85/−38
- src/Plots/Types.hs +4/−4
- src/Plots/Types/Bar.hs +2/−0
- src/Plots/Types/HeatMap.hs +54/−25
- src/Plots/Types/Histogram.hs +2/−2
- src/Plots/Types/Line.hs +1/−1
- src/Plots/Types/Pie.hs +3/−1
- src/Plots/Types/Scatter.hs +41/−2
README.md view
@@ -2,7 +2,9 @@ [](https://cchalmers.github.io/plots/) [](https://travis-ci.org/cchalmers/plots)+[](https://hackage.haskell.org/package/plots) + `plots` is a plotting library based on [diagrams](http://projects.haskell.org/diagrams). Some sample plots:@@ -25,7 +27,8 @@ the examples, first ensure that you have `stack` installed, and that you have a `stack.yaml` file in this directory that contains the lines: -```yaml packages:+```yaml+packages: - '.' - 'test' ```@@ -41,3 +44,9 @@ file (`examples_output/X.png`) does not exist, or if the source file (`examples/X.hs`) has been modified since the last time the script was run.++**Note 2:** If the `RunExamples` script fails with errors such as+ `Failed to load interface for ...` then you will need to `stack+ install` the required packages. In my case (with a freshly installed+ stack), I needed to run the following `stack install wreq cassava+ diagrams-rasterific`.
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
+ diagrams/src_Plots_Types_Scatter_bubbleExample.svg view
@@ -0,0 +1,1 @@+<svg xmlns="http://www.w3.org/2000/svg" height="350.0000" stroke-opacity="1" viewBox="0 0 412 350" font-size="1" width="411.5234" xmlns:xlink="http://www.w3.org/1999/xlink" stroke="rgb(0,0,0)" version="1.1"><defs></defs><g stroke-width="0.8"><path d="M 35.5469,266.8988 h 273.4375 M 35.5469,217.3630 h 273.4375 M 35.5469,167.8272 h 273.4375 M 35.5469,118.2914 h 273.4375 M 35.5469,68.7557 h 273.4375 "/></g><g stroke-linecap="square"><path d="M 35.5469,314.4531 v -273.4375 M 308.9844,314.4531 v -273.4375 "/></g><g stroke-width="0.4"><path d="M 308.9844,308.1786 h 2.0508 M 308.9844,299.9226 h 2.0508 M 308.9844,291.6667 h 2.0508 M 308.9844,283.4107 h 2.0508 M 308.9844,275.1547 h 2.0508 M 308.9844,258.6428 h 2.0508 M 308.9844,250.3869 h 2.0508 M 308.9844,242.1309 h 2.0508 M 308.9844,233.8749 h 2.0508 M 308.9844,225.6190 h 2.0508 M 308.9844,209.1070 h 2.0508 M 308.9844,200.8511 h 2.0508 M 308.9844,192.5951 h 2.0508 M 308.9844,184.3391 h 2.0508 M 308.9844,176.0832 h 2.0508 M 308.9844,159.5713 h 2.0508 M 308.9844,151.3153 h 2.0508 M 308.9844,143.0593 h 2.0508 M 308.9844,134.8034 h 2.0508 M 308.9844,126.5474 h 2.0508 M 308.9844,110.0355 h 2.0508 M 308.9844,101.7795 h 2.0508 M 308.9844,93.5236 h 2.0508 M 308.9844,85.2676 h 2.0508 M 308.9844,77.0116 h 2.0508 M 308.9844,60.4997 h 2.0508 M 308.9844,52.2437 h 2.0508 M 308.9844,43.9878 h 2.0508 "/></g><g stroke-width="0.4"><path d="M 308.9844,266.8988 h 3.4180 M 308.9844,217.3630 h 3.4180 M 308.9844,167.8272 h 3.4180 M 308.9844,118.2914 h 3.4180 M 308.9844,68.7557 h 3.4180 "/></g><g stroke-width="0.4"><path d="M 33.4961,308.1786 h 2.0508 M 33.4961,299.9226 h 2.0508 M 33.4961,291.6667 h 2.0508 M 33.4961,283.4107 h 2.0508 M 33.4961,275.1547 h 2.0508 M 33.4961,258.6428 h 2.0508 M 33.4961,250.3869 h 2.0508 M 33.4961,242.1309 h 2.0508 M 33.4961,233.8749 h 2.0508 M 33.4961,225.6190 h 2.0508 M 33.4961,209.1070 h 2.0508 M 33.4961,200.8511 h 2.0508 M 33.4961,192.5951 h 2.0508 M 33.4961,184.3391 h 2.0508 M 33.4961,176.0832 h 2.0508 M 33.4961,159.5713 h 2.0508 M 33.4961,151.3153 h 2.0508 M 33.4961,143.0593 h 2.0508 M 33.4961,134.8034 h 2.0508 M 33.4961,126.5474 h 2.0508 M 33.4961,110.0355 h 2.0508 M 33.4961,101.7795 h 2.0508 M 33.4961,93.5236 h 2.0508 M 33.4961,85.2676 h 2.0508 M 33.4961,77.0116 h 2.0508 M 33.4961,60.4997 h 2.0508 M 33.4961,52.2437 h 2.0508 M 33.4961,43.9878 h 2.0508 "/></g><g stroke-width="0.4"><path d="M 32.1289,266.8988 h 3.4180 M 32.1289,217.3630 h 3.4180 M 32.1289,167.8272 h 3.4180 M 32.1289,118.2914 h 3.4180 M 32.1289,68.7557 h 3.4180 "/></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,27.3438,68.7557)" stroke="none" text-anchor="end">6.0</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,27.3438,118.2914)" stroke="none" text-anchor="end">5.0</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,27.3438,167.8272)" stroke="none" text-anchor="end">4.0</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,27.3438,217.3630)" stroke="none" text-anchor="end">3.0</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,27.3438,266.8988)" stroke="none" text-anchor="end">2.0</text></g><g stroke-width="0.8"><path d="M 58.3333,314.4531 v -273.4375 M 103.9062,314.4531 v -273.4375 M 149.4792,314.4531 v -273.4375 M 195.0521,314.4531 v -273.4375 M 240.6250,314.4531 v -273.4375 M 286.1979,314.4531 v -273.4375 "/></g><g stroke-linecap="square"><path d="M 35.5469,314.4531 h 273.4375 M 35.5469,41.0156 h 273.4375 "/></g><g stroke-width="0.4"><path d="M 35.5469,41.0156 v -2.0508 M 43.1424,41.0156 v -2.0508 M 50.7378,41.0156 v -2.0508 M 65.9288,41.0156 v -2.0508 M 73.5243,41.0156 v -2.0508 M 81.1198,41.0156 v -2.0508 M 88.7153,41.0156 v -2.0508 M 96.3108,41.0156 v -2.0508 M 111.5017,41.0156 v -2.0508 M 119.0972,41.0156 v -2.0508 M 126.6927,41.0156 v -2.0508 M 134.2882,41.0156 v -2.0508 M 141.8837,41.0156 v -2.0508 M 157.0747,41.0156 v -2.0508 M 164.6701,41.0156 v -2.0508 M 172.2656,41.0156 v -2.0508 M 179.8611,41.0156 v -2.0508 M 187.4566,41.0156 v -2.0508 M 202.6476,41.0156 v -2.0508 M 210.2431,41.0156 v -2.0508 M 217.8385,41.0156 v -2.0508 M 225.4340,41.0156 v -2.0508 M 233.0295,41.0156 v -2.0508 M 248.2205,41.0156 v -2.0508 M 255.8160,41.0156 v -2.0508 M 263.4115,41.0156 v -2.0508 M 271.0069,41.0156 v -2.0508 M 278.6024,41.0156 v -2.0508 M 293.7934,41.0156 v -2.0508 M 301.3889,41.0156 v -2.0508 "/></g><g stroke-width="0.4"><path d="M 58.3333,41.0156 v -3.4180 M 103.9062,41.0156 v -3.4180 M 149.4792,41.0156 v -3.4180 M 195.0521,41.0156 v -3.4180 M 240.6250,41.0156 v -3.4180 M 286.1979,41.0156 v -3.4180 "/></g><g stroke-width="0.4"><path d="M 35.5469,316.5039 v -2.0508 M 43.1424,316.5039 v -2.0508 M 50.7378,316.5039 v -2.0508 M 65.9288,316.5039 v -2.0508 M 73.5243,316.5039 v -2.0508 M 81.1198,316.5039 v -2.0508 M 88.7153,316.5039 v -2.0508 M 96.3108,316.5039 v -2.0508 M 111.5017,316.5039 v -2.0508 M 119.0972,316.5039 v -2.0508 M 126.6927,316.5039 v -2.0508 M 134.2882,316.5039 v -2.0508 M 141.8837,316.5039 v -2.0508 M 157.0747,316.5039 v -2.0508 M 164.6701,316.5039 v -2.0508 M 172.2656,316.5039 v -2.0508 M 179.8611,316.5039 v -2.0508 M 187.4566,316.5039 v -2.0508 M 202.6476,316.5039 v -2.0508 M 210.2431,316.5039 v -2.0508 M 217.8385,316.5039 v -2.0508 M 225.4340,316.5039 v -2.0508 M 233.0295,316.5039 v -2.0508 M 248.2205,316.5039 v -2.0508 M 255.8160,316.5039 v -2.0508 M 263.4115,316.5039 v -2.0508 M 271.0069,316.5039 v -2.0508 M 278.6024,316.5039 v -2.0508 M 293.7934,316.5039 v -2.0508 M 301.3889,316.5039 v -2.0508 "/></g><g stroke-width="0.4"><path d="M 58.3333,317.8711 v -3.4180 M 103.9062,317.8711 v -3.4180 M 149.4792,317.8711 v -3.4180 M 195.0521,317.8711 v -3.4180 M 240.6250,317.8711 v -3.4180 M 286.1979,317.8711 v -3.4180 "/></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="text-before-edge" transform="matrix(1.0000,0.0000,0.0000,1.0000,286.1979,322.6562)" stroke="none" text-anchor="middle">3.5</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="text-before-edge" transform="matrix(1.0000,0.0000,0.0000,1.0000,240.6250,322.6562)" stroke="none" text-anchor="middle">3.0</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="text-before-edge" transform="matrix(1.0000,0.0000,0.0000,1.0000,195.0521,322.6562)" stroke="none" text-anchor="middle">2.5</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="text-before-edge" transform="matrix(1.0000,0.0000,0.0000,1.0000,149.4792,322.6562)" stroke="none" text-anchor="middle">2.0</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="text-before-edge" transform="matrix(1.0000,0.0000,0.0000,1.0000,103.9062,322.6562)" stroke="none" text-anchor="middle">1.5</text></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="text-before-edge" transform="matrix(1.0000,0.0000,0.0000,1.0000,58.3333,322.6562)" stroke="none" text-anchor="middle">1.0</text></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(77,175,74)" stroke-width="1.0" fill="rgb(114,185,112)"><defs><clipPath id="myClip1"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip1)"><path d="M 293.7174,124.8035 l -7.5195,-13.0242 l -7.5195,13.0242 Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(77,175,74)" stroke-width="1.0" fill="rgb(114,185,112)"><defs><clipPath id="myClip2"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip2)"><path d="M 262.2380,240.1078 l -3.3838,-5.8609 l -3.3838,5.8609 Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(77,175,74)" stroke-width="1.0" fill="rgb(114,185,112)"><defs><clipPath id="myClip3"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip3)"><path d="M 160.7585,123.1060 l -11.2793,-19.5363 l -11.2793,19.5363 Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(77,175,74)" stroke-width="1.0" fill="rgb(114,185,112)"><defs><clipPath id="myClip4"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip4)"><path d="M 80.3223,235.4798 l -3.7598,-6.5121 l -3.7598,6.5121 Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(55,126,184)" stroke-width="1.0" fill="rgb(103,146,193)"><defs><clipPath id="myClip5"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip5)"><path d="M 287.5138,216.2021 l -0.0000,-2.6318 h -2.6318 l -0.0000,2.6318 Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(55,126,184)" stroke-width="1.0" fill="rgb(103,146,193)"><defs><clipPath id="myClip6"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip6)"><path d="M 262.2380,220.7468 l -0.0000,-6.7676 h -6.7676 l -0.0000,6.7676 Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(55,126,184)" stroke-width="1.0" fill="rgb(103,146,193)"><defs><clipPath id="myClip7"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip7)"><path d="M 151.9230,232.1908 l -0.0000,-4.8877 h -4.8877 l -0.0000,4.8877 Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(55,126,184)" stroke-width="1.0" fill="rgb(103,146,193)"><defs><clipPath id="myClip8"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip8)"><path d="M 62.0931,295.4264 l -0.0000,-7.5195 h -7.5195 l -0.0000,7.5195 Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(228,26,28)" stroke-width="1.0" fill="rgb(231,93,93)"><defs><clipPath id="myClip9"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip9)"><path d="M 288.8298,63.8021 c 0.0000,-1.4535 -1.1783,-2.6318 -2.6318 -2.6318c -1.4535,-0.0000 -2.6318,1.1783 -2.6318 2.6318c -0.0000,1.4535 1.1783,2.6318 2.6318 2.6318c 1.4535,0.0000 2.6318,-1.1783 2.6318 -2.6318Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(228,26,28)" stroke-width="1.0" fill="rgb(231,93,93)"><defs><clipPath id="myClip10"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip10)"><path d="M 265.6217,68.7557 c 0.0000,-3.7376 -3.0299,-6.7676 -6.7676 -6.7676c -3.7376,-0.0000 -6.7676,3.0299 -6.7676 6.7676c -0.0000,3.7376 3.0299,6.7676 6.7676 6.7676c 3.7376,0.0000 6.7676,-3.0299 6.7676 -6.7676Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(228,26,28)" stroke-width="1.0" fill="rgb(231,93,93)"><defs><clipPath id="myClip11"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip11)"><path d="M 154.3669,93.5236 c 0.0000,-2.6994 -2.1883,-4.8877 -4.8877 -4.8877c -2.6994,-0.0000 -4.8877,2.1883 -4.8877 4.8877c -0.0000,2.6994 2.1883,4.8877 4.8877 4.8877c 2.6994,0.0000 4.8877,-2.1883 4.8877 -4.8877Z"/></g></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(228,26,28)" stroke-width="1.0" fill="rgb(231,93,93)"><defs><clipPath id="myClip12"><path d="M 308.9844,314.4531 l -0.0000,-273.4375 h -273.4375 l -0.0000,273.4375 Z"/></clipPath></defs><g clip-path="url(#myClip12)"><path d="M 65.8529,217.3630 c 0.0000,-4.1529 -3.3666,-7.5195 -7.5195 -7.5195c -4.1529,-0.0000 -7.5195,3.3666 -7.5195 7.5195c -0.0000,4.1529 3.3666,7.5195 7.5195 7.5195c 4.1529,0.0000 7.5195,-3.3666 7.5195 -7.5195Z"/></g></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="text-after-edge" transform="matrix(1.0000,0.0000,0.0000,1.0000,172.2656,27.3438)" stroke="none" text-anchor="middle"></text></g><g fill-opacity="0.0" fill="rgb(0,0,0)"><path d="M 380.7617,82.0312 l -0.0000,-41.0156 h -58.1055 l -0.0000,41.0156 Z"/></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,343.1641,75.1953)" stroke="none" text-anchor="start">data 9</text></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(77,175,74)" stroke-width="1.0" fill="rgb(114,185,112)"><path d="M 336.6699,78.4514 l -3.7598,-6.5121 l -3.7598,6.5121 Z"/></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,343.1641,61.5234)" stroke="none" text-anchor="start">data 8</text></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(55,126,184)" stroke-width="1.0" fill="rgb(103,146,193)"><path d="M 336.6699,65.2832 l -0.0000,-7.5195 h -7.5195 l -0.0000,7.5195 Z"/></g><g fill-opacity="1.0" font-size="11.0px" fill="rgb(0,0,0)"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,343.1641,47.8516)" stroke="none" text-anchor="start">data 7</text></g><g stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(228,26,28)" stroke-width="1.0" fill="rgb(231,93,93)"><path d="M 336.6699,47.8516 c 0.0000,-2.0765 -1.6833,-3.7598 -3.7598 -3.7598c -2.0765,-0.0000 -3.7598,1.6833 -3.7598 3.7598c -0.0000,2.0765 1.6833,3.7598 3.7598 3.7598c 2.0765,0.0000 3.7598,-1.6833 3.7598 -3.7598Z"/></g></svg>
plots.cabal view
@@ -1,5 +1,5 @@ name: plots-version: 0.1.0.2+version: 0.1.1.0 synopsis: Diagrams based plotting library. homepage: http://github.com/cchalmers/plots license: BSD3@@ -10,7 +10,7 @@ stability: Experimental category: Graphics build-type: Simple-cabal-version: >=1.10+cabal-version: >=1.18 extra-source-files: README.md diagrams/*.svg extra-doc-files: diagrams/*.svg description: Diagrams based plotting library.@@ -47,7 +47,7 @@ Diagrams.Coordinates.Polar hs-source-dirs: src build-depends:- base >= 4.3 && < 5.0,+ base >= 4.7 && < 5.0, adjunctions, colour, containers >= 0.3 && < 0.6,
src/Diagrams/Coordinates/Polar.hs view
@@ -136,9 +136,9 @@ etheta = eθ -- | Coordinate with at least one dimension where the x coordinate can be--- retreived numerically. Note this differs slightly from 'R1' which requires+-- retrieved numerically. Note this differs slightly from 'R1' which requires -- a lens for all values. This allows instances for different coordinates--- such as 'Polar', where the x coordinate can only be retreived numerically.+-- such as 'Polar', where the x coordinate can only be retrieved numerically. class HasX t where x_ :: RealFloat n => Lens' (t n) n
src/Plots.hs view
@@ -49,10 +49,10 @@ -- ** Histogram plot - -- | Histogram. API for histogram.+ -- | Histogram. API for histograms. , module Plots.Types.Histogram - -- | Wedge and annular wedge. API for wedge, annular wegde and pie.+ -- | Wedge and annular wedge. API for wedge, annular wedge and pie. , module Plots.Types.Pie --------------------------------------------------------------------@@ -60,7 +60,7 @@ -------------------------------------------------------------------- -- | Definitions of bounds, axis scale, orientation, legend, generic- -- plot ,plot spec and so on.+ -- plot, plot spec and so on. , module Plots.Types -- | Grid lines and styles.@@ -69,7 +69,7 @@ -- | Grid lines and styles. , module Plots.Axis.Grid - -- | Axis labels and tick labels .+ -- | Axis labels and tick labels. , module Plots.Axis.Labels -- | Rendering system for polar and r2 axis.@@ -87,7 +87,7 @@ -- | Colour bars. , module Plots.Axis.ColourBar - -- | Polar coordinates+ -- | Polar coordinates. , module Diagrams.Coordinates.Polar , (&=), (&~~)
src/Plots/Axis.hs view
@@ -14,7 +14,7 @@ -- Portability : non-portable -- -- The 'Axis' is the main data type for "plots". It holds all the--- nessesary infomation to be rendered into a 'Diagram'.+-- necessary infomation to be rendered into a 'Diagram'. -- ---------------------------------------------------------------------------- module Plots.Axis@@ -100,7 +100,7 @@ -- Single axis --------------------------------------------------------- --- | Render infomation for a single axis line.+-- | Render information for a single axis line. data SingleAxis b v n = SingleAxis -- note the the v is only present for Style v n { saLabel :: AxisLabel b v n@@ -183,7 +183,7 @@ -- Axis data type ------------------------------------------------------ --- | Axis is the data type that holds all the nessessary information to render+-- | Axis is the data type that holds all the necessary information to render -- a plot. Common 'LensLike's used for the axis (see haddock's -- instances for a more comprehensive list): --@@ -211,7 +211,7 @@ -- * 'axisScaling' - customise the 'AxisScaling' -- -- Plots are usually added to the axis using specific functions for--- that plots ('Plots.Types.Line.linePlot, 'Plots.Types.Bar.barPlot').+-- those plots ('Plots.Types.Line.linePlot, 'Plots.Types.Bar.barPlot'). -- These functions use 'addPlotable' to add the plot to the axis. data Axis b c n = Axis { _axisStyle :: AxisStyle b (BaseSpace c) n@@ -322,7 +322,7 @@ axisSize :: (HasLinearMap c, Num n, Ord n) => Lens' (Axis b c n) (SizeSpec c n) axisSize = axes . column renderSize . iso mkSizeSpec getSpec -- column axisScaling . asSizeSpec -- iso mkSizeSpec getSpec --- | The range used for the colour bar limits. This is automaticlaly set+-- | The range used for the colour bar limits. This is automatically set -- when using 'heatMap' or 'heatMap'' colourBarRange :: Lens' (Axis b v n) (n,n) colourBarRange = lens _colourBarR (\a r -> a {_colourBarR = r})@@ -368,7 +368,7 @@ -> m () -- ^ add plot to the 'Axis' addPlot p = axisPlots <>= [DynamicPlot p] --- | Add something 'Plotable' to the 'Axis' with a statefull modification+-- | Add something 'Plotable' to the 'Axis' with a stateful modification -- of the 'Plot'. addPlotable :: (InSpace (BaseSpace c) n p, MonadState (Axis b c n) m, Plotable p b)
src/Plots/Axis/ColourBar.hs view
@@ -57,6 +57,7 @@ { cbPlacement :: Placement , cbVisible :: Bool , cbTicks :: MajorTicks V2 n+ , cbMinorTicks :: MinorTicks V2 n , cbGridLines :: MajorGridLines V2 n , cbTickLabels :: TickLabels b V2 n , cbDraw :: ColourMap -> QDiagram b V2 n Any@@ -76,6 +77,7 @@ { cbPlacement = rightMid , cbVisible = False , cbTicks = def+ , cbMinorTicks = def & hidden .~ True , cbGridLines = def , cbTickLabels = def , cbDraw = gradientColourBar@@ -187,6 +189,12 @@ instance Functor f => HasMajorTicks f (ColourBar b n) where majorTicks = lens cbTicks (\c a -> c {cbTicks = a}) +instance Functor f => HasMinorTicks f (ColourBar b n) where+ minorTicks = lens cbMinorTicks (\c a -> c {cbMinorTicks = a})++instance Functor f => HasMajorGridLines f (ColourBar b n) where+ majorGridLines = lens cbGridLines (\c a -> c {cbGridLines = a})+ instance Functor f => HasTickLabels f (ColourBar b n) b where tickLabel = lens cbTickLabels (\c a -> c {cbTickLabels = a}) @@ -247,7 +255,7 @@ f x = (x - (ub + lb)/2) / (ub - lb) * l inRange x = x >= lb && x <= ub - bar = outline <> tks <> gLines <> colours+ bar = outline <> tks <> minorTks <> gLines <> colours -- the outline outline = rect l w # applyStyle (cbStyle & _fillTexture .~ _AC ## transparent)@@ -261,8 +269,17 @@ tks | cbTicks ^. hidden = mempty | otherwise = F.foldMap (\x -> aTick # translate (V2 (f x) (-w/2))) tickXs'+ # applyStyle (cbTicks ^. majorTicksStyle) aTick = someTick (cbTicks ^. majorTicksAlignment) (cbTicks ^. majorTicksLength) + minorTickXs = view minorTicksFunction cbMinorTicks tickXs bnds+ minorTickXs' = filter inRange minorTickXs+ minorTks+ | cbMinorTicks ^. hidden = mempty+ | otherwise = F.foldMap (\x -> aMinorTick # translate (V2 (f x) (-w/2))) minorTickXs'+ # applyStyle (cbMinorTicks ^. minorTicksStyle)+ aMinorTick = someTick (cbTicks ^. majorTicksAlignment) (cbTicks ^. majorTicksLength)+ someTick tType d = case tType of TickSpec (fromRational -> aa) (fromRational -> bb) -> mkP2 0 (-d*bb) ~~ mkP2 0 (d*aa)@@ -324,7 +341,7 @@ where mkR i x = rect d' 1 # alignR- # fcA (cm ^. ixColour (x - 1/(2*fromIntegral n)))+ # fc (cm ^. ixColourR (x - 1/(2*fromIntegral n))) # translateX (fromRational x) # lw none where
src/Plots/Axis/Grid.hs view
@@ -14,7 +14,7 @@ -- Stability : experimental -- Portability : non-portable ----- Lines that go along the axis. Supports major and minor gird lines+-- Lines that go along the axis. Supports major and minor grid lines -- separately for each axis. -- ----------------------------------------------------------------------------@@ -193,7 +193,7 @@ -- Both grid lines ------------------------------------------------------------------------ --- | Type holding infomation about both major and minor grid lines.+-- | Type holding information about both major and minor grid lines. data GridLines v n = GridLines { majGrid :: MajorGridLines v n , minGrid :: MinorGridLines v n@@ -228,7 +228,7 @@ -- @ -- 'hideGridLines' :: 'Axis' b c n -> 'Axis' b c n -- 'hideGridLines' :: 'SingleAxis' b c n -> 'SingleAxis' b c n--- 'hideGridLines' :: 'GridLines' b c n -> 'GirdLines' b c n+-- 'hideGridLines' :: 'GridLines' b c n -> 'GridLines' b c n -- @ hideGridLines :: (HasGridLines Identity a, MonadState a m) => m () hideGridLines = do@@ -240,14 +240,14 @@ -- @ -- 'showGridLines' :: 'Axis' b c n -> 'Axis' b c n -- 'showGridLines' :: 'SingleAxis' b c n -> 'SingleAxis' b c n--- 'showGridLines' :: 'GridLines' b c n -> 'GirdLines' b c n+-- 'showGridLines' :: 'GridLines' b c n -> 'GridLines' b c n -- @ showGridLines :: (HasGridLines Identity a, MonadState a m) => m () showGridLines = do minorGridLines . visible .= True majorGridLines . visible .= True --- | Traversal over both the major and minor grid styles. This can be used at seversal levels in the Axis:+-- | Traversal over both the major and minor grid styles. This can be used at several levels in the axis: gridLinesStyle :: (HasGridLines f a, Applicative f) => LensLike' f a (Style (V a) (N a)) gridLinesStyle = gridLines . styles where styles :: Traversal' (GridLines v n) (Style v n)
src/Plots/Axis/Labels.hs view
@@ -8,13 +8,15 @@ ----------------------------------------------------------------------------- -- | -- Module : Plots.Axis.Labels--- Copyright : (C) 2015 Christopher Chalmers+-- Copyright : (C) 2015-2017 Christopher Chalmers -- License : BSD-style (see the file LICENSE) -- Maintainer : Christopher Chalmers -- Stability : experimental -- Portability : non-portable ----- Low level module defining types for axis labels and tick labels.+-- There are two kinds of labels this module deals with: The 'AxisLabel'+-- labels are placed next to an axis line. The 'TickLabels' are the+-- numbers (usually) next to each major tick on an axis line. -- ---------------------------------------------------------------------------- module Plots.Axis.Labels@@ -56,11 +58,22 @@ | LowerAxisLabel | UpperAxisLabel --- | Whether the 'AxisLabel' should be inside or ouside the axis.+-- | Whether the 'AxisLabel' should be inside or outside the axis. data AxisLabelPlacement = InsideAxisLabel | OutsideAxisLabel +-- | 'AxisLabel' describes the label next to each axis line. They are+-- normally set with the 'Plots.Axis.xLabel' and 'Plots.Axis.yLabel'+-- helper function:+--+-- @+-- myAxis = r2Axis &~ do+-- 'Plots.Axis.xLabel' .= "time (s)"+-- 'Plots.Axis.yLabel' .= "height (m)"+-- @+--+-- See 'HasAxisLabel' for more advanced settings. data AxisLabel b v n = AxisLabel { alFun :: TextFunction b v n , alText :: String@@ -102,7 +115,7 @@ axisLabelStyle :: Functor f => LensLike' f a (Style (V a) (N a)) axisLabelStyle = axisLabel . lens alStyle (\al sty -> al {alStyle = sty}) - -- | The position the label will be placed parallel the axis.+ -- | The position the label will be placed parallel to the axis. axisLabelPosition :: Functor f => LensLike' f a AxisLabelPosition axisLabelPosition = axisLabel . lens alPos (\al sty -> al {alPos = sty}) @@ -140,8 +153,8 @@ -- Tick labels ------------------------------------------------------------------------ --- Labels that are placed next to the ticks of an axis.-+-- | 'TickLabels' describes how to draw the labels next to ticks. See+-- 'HasTickLabels' for more options. data TickLabels b v n = TickLabels { tlFun :: [n] -> (n,n) -> [(n, String)] , tlTextFun :: TextFunction b v n@@ -170,7 +183,7 @@ tickLabelTextFunction :: Functor f => LensLike' f a (TextFunction b (V a) (N a)) tickLabelTextFunction = tickLabel . lens tlTextFun (\tl f -> tl {tlTextFun = f}) - -- | Tick labels functions are used to draw the tick labels. They has+ -- | Tick labels functions are used to draw the tick labels. They have -- access to the major ticks and the current bounds. Returns the -- position of the tick and label to use at that position. --@@ -211,9 +224,18 @@ visible = lens tlVisible (\tl b -> tl {tlVisible = b}) -- | Setter over the final positions the major ticks. This is not as--- general as 'minorTicksFunction' because you don't have access to--- the bounds but it can be useful when you know exactly what ticks--- you want to add or modify existing tick positions.+-- general as 'tickLabelFunction' because you don't have access to the+-- bounds but it can be useful when you know exactly what ticks you+-- want to add or modify existing tick positions or to add an extra+-- value:+--+-- @+-- xAxis . tickLabelPositions .= [(1, "apples"), (2, "oranges"), (3, "bananas"]+-- yAxis . tickLabelPositions <>= [(1.5, "critial mass")]+-- @+--+-- If you want to change or add normal ticks see 'majorTicksFunction'.+-- tickLabelPositions :: (HasTickLabels f a b, Settable f) => LensLike' f a [(N a, String)]
src/Plots/Axis/Render.hs view
@@ -301,8 +301,8 @@ | otherwise = foldMap mkline (map snd ys) -- merge with ticks? # transform t # stroke- -- # applyStyle (a ^. axisLine e . axisArrowOpts . _Just . shaftStyle) # lineCap LineCapSquare+ # applyStyle (a^.axisLineStyle) where -- TODO: Arrow for R3 mkline y = pathFromVertices@@ -544,7 +544,7 @@ -- Angular axis ---------------------------------------------------------------------- - -- The angular axis is a circular line around the perimieter of the+ -- The angular axis is a circular line around the perimeter of the -- polar plot. The Ticks and tick labels are placed around this -- perimeter. The Grid lines go from the perimeter to the center. thetaAx@@ -614,7 +614,7 @@ -- grid lines go from the centre of the axis to the perimeter thetaAxGridLines- -- - | thetaA ^. girdLines . hidden = mempty+ -- - | thetaA ^. gridLines . hidden = mempty | otherwise = thetaMajorGridLines <> thetaMinorGridLines majorGridThetas = view majorGridLinesFunction thetaA majorTickThetas (0,theta)
src/Plots/Axis/Title.hs view
@@ -36,6 +36,7 @@ , tTxtFun :: TextAlignment n -> String -> QDiagram b v n Any , tStyle :: Style v n , tPlacement :: Placement+ , tAlignment :: TextAlignment n , tGap :: n } deriving Typeable @@ -47,6 +48,7 @@ , tTxtFun = mkText , tStyle = mempty # fontSize (output 11) , tPlacement = midAbove+ , tAlignment = BoxAlignedText 0.5 0 , tGap = 20 } @@ -84,6 +86,19 @@ titlePlacement :: Lens' a Placement titlePlacement = title . lens tPlacement (\t s -> t {tPlacement = s}) + -- | The function used to draw the title text.+ --+ -- Default is 'mkText'.+ titleTextFunction :: Lens' a (TextAlignment (N a) -> String -> QDiagram b (V a) (N a) Any)+ titleTextFunction = title . lens tTxtFun (\t s -> t {tTxtFun = s})++ -- | The 'TextAlignment' used for the title text. This is given to the+ -- 'titleTextFunction'.+ --+ -- Default is @'BoxAlignedText' 0.5 0@.+ titleAlignment :: Lens' a (TextAlignment (N a))+ titleAlignment = title . lens tAlignment (\t s -> t {tAlignment = s})+ -- | The gap between the axis and the title. -- -- Default is 'mempty'.@@ -107,6 +122,6 @@ (t ^. titleGap) tDia where- tDia = tTxtFun t (BoxAlignedText 0.5 0) (tTxt t)+ tDia = tTxtFun t (t ^. titleAlignment) (tTxt t) # applyStyle (tStyle t)
src/Plots/Legend.hs view
@@ -137,14 +137,20 @@ # orient (l ^. legendOrientation) hcat vcat # alignTL - back = rect (w + h + 5) (h * fromIntegral (length entries))- # fcA transparent+ back = backRect # applyStyle (l ^. legendStyle) # alignTL- # translate (V2 (-5) 0) -- (-3))+ backRect = orient (l ^. legendOrientation)+ (rect (nEntries * entryWidth) h )+ (rect entryWidth (h * nEntries))+ nEntries = fromIntegral (length entries) - -- mkLabels :: (QDiagram b V2 n Any, String) -> QDiagram b V2 n Any- mkLabels (pic, txt) = pic' ||| strutX 5 ||| label where+ -- Each legend picture has a width equal to the height of each+ -- legend entry. The picture also has a 5 unit buffer either side of+ -- it.+ entryWidth = w + 10 + h++ mkLabels (pic, txt) = strutX 5 ||| pic' ||| strutX 5 ||| label where pic' = pic # withEnvelope (fromCorners (pure (-h/2)) (pure (h/2))) label = view legendTextFunction l txt # applyStyle (l ^. legendTextStyle)
src/Plots/Style.hs view
@@ -26,7 +26,6 @@ ( -- * The axis style AxisStyle , HasAxisStyle (..)- -- , axisStyles -- ** Predefined styles , fadedColours@@ -58,12 +57,15 @@ -- * Colour maps , ColourMap , ixColour+ , ixColourR , cmTraverse , colourMap- , alphaColourMap , colourList , toStops + , NanColours+ , HasNanColours (..)+ -- ** Sample maps , viridis , magma@@ -73,7 +75,6 @@ ) where --- import Control.Lens hiding (transform, ( # ), at, none) import qualified Control.Lens as Lens import Data.Colour.SRGB import qualified Data.Map as M@@ -273,7 +274,7 @@ ------------------------------------------------------------------------ -- | The 'AxisStyle' determines the 'Style's of the plots in an axis.--- There are various predifined styles to change the look of the plot.+-- There are various predefined styles to change the look of the plot. data AxisStyle b v n = AxisStyle ColourMap [PlotStyle b v n] type instance V (AxisStyle b v n) = v@@ -459,52 +460,101 @@ -- Colour maps ------------------------------------------------------------------------ --- type ColourMap = [(Double, AlphaColour Double)]+-- | Colours to use when representing @NaN@, @Infinity@ and @-Infinity@.+data NanColours = NanColours+ { _nanColour :: Colour Double+ , _infColour :: Colour Double+ , _negInfColour :: Colour Double+ } deriving Show +class HasNanColours a where+ -- | Colours to use when displaying @NaN@, @Infinity@ and @-Infinity@.+ nanColours :: Lens' a NanColours++ -- | Colour to use when displaying @NaN@.+ --+ -- Default is 'white.+ nanColour :: Lens' a (Colour Double)+ nanColour = nanColours . lens _nanColour (\n c -> n {_nanColour = c})++ -- | Colour to use when displaying @Infinity@.+ --+ -- Default is 'lime'.+ infColour :: Lens' a (Colour Double)+ infColour = nanColours . lens _infColour (\n c -> n {_infColour = c})++ -- | Colour to use when displaying @-Infinity@.+ --+ -- Default is 'magenta'.+ negInfColour :: Lens' a (Colour Double)+ negInfColour = nanColours . lens _negInfColour (\n c -> n {_negInfColour = c})++instance HasNanColours NanColours where+ nanColours = id++instance Default NanColours where+ def = NanColours+ { _nanColour = magenta+ , _infColour = white+ , _negInfColour = black+ }++-- type ColourMap = [(Double, Colour Double)]+ -- | A map from a number (usually between 0 and 1) to a colour. Colour -- maps are part of the 'AxisStyle', which is used for plots like -- 'Plots.Types.HeatMap'.-newtype ColourMap = ColourMap (M.Map Rational (AlphaColour Double))+data ColourMap = ColourMap NanColours (M.Map Rational (Colour Double)) deriving Show - type instance V ColourMap = V1 type instance N ColourMap = Rational --- makeWrapped ''ColourMap--- manually write instance to avoid template haskell splitting the--- module up-instance Rewrapped ColourMap ColourMap-instance Wrapped ColourMap where- type Unwrapped ColourMap = M.Map Rational (AlphaColour Double)- _Wrapped' = iso (\(ColourMap a) -> a) ColourMap- {-# INLINE _Wrapped' #-}+cmap :: Lens' ColourMap (M.Map Rational (Colour Double))+cmap f (ColourMap ncs cs) = f cs <&> \cs' -> ColourMap ncs cs' +instance HasNanColours ColourMap where+ nanColours f (ColourMap ncs cs) = f ncs <&> \ncs' -> ColourMap ncs' cs+ p1apply :: Num a => Transformation V1 a -> a -> a p1apply t a = papply t (P (V1 a)) ^. _x instance Transformable ColourMap where- transform t = over (_Wrapped' . _Wrapped' . mapped . _1) (p1apply t)+ transform t = over (cmap . _Wrapped' . mapped . _1) (p1apply t) type instance Index ColourMap = Rational-type instance IxValue ColourMap = AlphaColour Double--instance AsEmpty ColourMap where- _Empty = nearly (ColourMap M.empty) (allOf each (==transparent))+type instance IxValue ColourMap = Colour Double -instance Each ColourMap ColourMap (AlphaColour Double) (AlphaColour Double) where- each = _Wrapped' . each+instance Each ColourMap ColourMap (Colour Double) (Colour Double) where+ each = cmap . each instance Ixed ColourMap where- ix = ixColour+ ix = ixColourR -- | 'Nothing' == 'transparent' instance At ColourMap where- at x = ixColour x . from (non transparent)+ at x = ixColourR x . from (non black) -ixColour :: Rational -> Lens' ColourMap (AlphaColour Double)-ixColour x f (ColourMap cm) = f c <&> \c' -> ColourMap (M.insert x c' cm)+ixColour :: Double -> Lens' ColourMap (Colour Double)+ixColour x f cM@(ColourMap ncs cm)+ | isNaN x = nanColour f cM+ | isInfinite x = if x < 0 then negInfColour f cM else infColour f cM+ | otherwise = f c <&> \c' -> ColourMap ncs (M.insert r c' cm) where+ r = toRational x+ c = case (M.lookupLE r cm, M.lookupGE r cm) of+ (Just (i,c1), Just (j,c2))+ | i == j -> c1+ | otherwise ->+ let a = fromRational $ (r - i) / (j - i)+ in blend a c2 c1+ (Just (_,c1), Nothing) -> c1+ (Nothing, Just (_,c2)) -> c2+ _ -> black++ixColourR :: Rational -> Lens' ColourMap (Colour Double)+ixColourR x f (ColourMap ncs cm) = f c <&> \c' -> ColourMap ncs (M.insert x c' cm)+ where c = case (M.lookupLE x cm, M.lookupGE x cm) of (Just (i,c1), Just (j,c2)) | i == j -> c1@@ -513,28 +563,25 @@ in blend a c2 c1 (Just (_,c1), Nothing) -> c1 (Nothing, Just (_,c2)) -> c2- _ -> transparent+ _ -> black -- | Indexed traversal over the colours indexed and ordered by their -- position in the map.-cmTraverse :: IndexedTraversal' Rational ColourMap (AlphaColour Double)-cmTraverse = _Wrapped' . itraversed+cmTraverse :: IndexedTraversal' Rational ColourMap (Colour Double)+cmTraverse = cmap . itraversed -- | Return the list of colours in the [0,1] range in order. This always -- includes colours 0 and 1.-colourList :: ColourMap -> [(Rational, AlphaColour Double)]+colourList :: ColourMap -> [(Rational, Colour Double)] colourList = itoListOf (cmTraverse . ifiltered (\i _ -> i >= 0 && i <= 1))- . (ixColour 0 %~ id) . (ixColour 1 %~ id)+ . (ixColourR 0 %~ id) . (ixColourR 1 %~ id) -- touch colours at 0 and 1 so they're in the list colourMap :: [(Rational, Colour Double)] -> ColourMap-colourMap = alphaColourMap . over (mapped . _2) opaque--alphaColourMap :: [(Rational, AlphaColour Double)] -> ColourMap-alphaColourMap [] = ColourMap M.empty-alphaColourMap cs- | a == b = ColourMap (M.singleton 0.5 c)- | otherwise = ColourMap (M.mapKeysMonotonic normalise cm)+colourMap [] = ColourMap def M.empty+colourMap cs+ | a == b = ColourMap def (M.singleton 0.5 c)+ | otherwise = ColourMap def (M.mapKeysMonotonic normalise cm) where cm = M.fromList cs (a,c) = M.findMin cm
src/Plots/Types.hs view
@@ -302,8 +302,8 @@ legendText :: Lens' (LegendEntry b v n) String legendText = lens lText (\l txt -> l {lText = txt}) --- | The order in which the legend entries are rendered. If precedence--- are equal, they entries are put in the order they are added to the+-- | The order in which the legend entries are rendered. If precedences+-- are equal, the entries are put in the order they are added to the -- axis. -- -- Default is @0@.@@ -635,7 +635,7 @@ _DynamicPlot :: (Plotable p b, Typeable b) => Prism' (DynamicPlot b (V p) (N p)) (Plot p b) _DynamicPlot = prism' DynamicPlot (\(DynamicPlot p) -> cast p) --- | Traversal over the dynamic plot without the Plotable constraint+-- | Traversal over the dynamic plot without the 'Plotable' constraint -- '_DynamicPlot' has. dynamicPlot :: forall p b. (Typeable p, Typeable b) => Traversal' (DynamicPlot b (V p) (N p)) (Plot p b)@@ -692,7 +692,7 @@ f sty <&> StyledPlot p opts -- | Traversal over a raw plot of a styled plot. The type of the plot--- must match for the traversal to be succesful.+-- must match for the traversal to be successful. styledPlot :: forall p b. Typeable p => Traversal' (StyledPlot b (V p) (N p)) p styledPlot f s@(StyledPlot p opts sty) = case eq p of
src/Plots/Types/Bar.hs view
@@ -22,6 +22,8 @@ -- -- <<diagrams/src_Plots_Types_Bar_multiBarExample.svg#diagram=multiBarExample&height=350>> --+-- (see 'multiBars' example for code to make this plot)+-- ---------------------------------------------------------------------------- module Plots.Types.Bar (
src/Plots/Types/HeatMap.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}@@ -23,6 +24,8 @@ -- -- <<diagrams/src_Plots_Types_HeatMap_heatMapIndexedExample.svg#diagram=heatMapIndexedExample&height=350>> --+-- (see 'heatMapIndexed' example for code to make this plot)+-- ---------------------------------------------------------------------------- module Plots.Types.HeatMap@@ -55,7 +58,6 @@ ) where import Control.Lens hiding (transform, ( # ))-import qualified Data.Colour as C import Control.Monad.ST import Control.Monad.State@@ -65,7 +67,6 @@ import qualified Data.Vector.Storable as S import qualified Data.Vector.Unboxed as V import Data.Word (Word8)-import Statistics.Function (minMax) import Codec.Picture import Diagrams.Coordinates.Isomorphic@@ -104,6 +105,32 @@ go 0 (1/0) (-1/0) 0 0 {-# INLINE mkHeatMatrix #-} +min' :: Double -> Double -> Double+min' !a !b+ | isNaN b = a+ | isInfinite b = a+ | otherwise = min a b+{-# INLINE min' #-}++max' :: Double -> Double -> Double+max' !a !b+ | isNaN b = a+ | isInfinite b = a+ | otherwise = max a b+{-# INLINE max' #-}++data MM = MM {-# UNPACK #-} !Double {-# UNPACK #-} !Double++-- | Compute the minimum and maximum of a vector in one pass. This+-- ignores any @Infinity@ or @NaN@ values (since these make no sense+-- for colour bar ranges).+minMax :: V.Vector Double -> (Double, Double)+minMax = fini . V.foldl' go (MM (1/0) (-1/0))+ where+ go (MM lo hi) k = MM (min' lo k) (max' hi k)+ fini (MM lo hi) = (lo, hi)+{-# INLINE minMax #-}+ -- | Construct a heat matrix from a foldable of foldables. -- -- @@@ -207,7 +234,7 @@ V2 x y = hmSize hm -- | Scale an image so each pixel takes (n*n) pixels. This can be--- usefull for using 'heatImage' on small heat matrixes to give a+-- useful for using 'heatImage' on small heat matrices to give a -- sharper image. scaleImage :: Int -> Image PixelRGB8 -> Image PixelRGB8 scaleImage n img | n == 1 = img@@ -234,30 +261,36 @@ -- | Create an image of 'PixelsRGB8' using the heat matrix. heatImage :: HeatMatrix -> ColourMap -> Image PixelRGB8-heatImage (HeatMatrix (V2 x y) dv a b) cm = Image x y v' where+heatImage (HeatMatrix (V2 x y) dv a b) cm = Image x y v where !cv = mkColourVector cm - -- PixelRGB8 doesn't have an unboxed instance so we have to write each- -- component manually.- v' = S.create $ do+ v :: S.Vector Word8+ v = S.create $ do mv <- M.new (3 * x * y) let !m = 256 / (b - a)- go s i q- | s == x-1 = do -- return mv- let !d = V.unsafeIndex dv s+ writeColour q (toSRGB24 -> RGB rr gg bb) = do+ M.unsafeWrite mv q rr+ M.unsafeWrite mv (q+1) gg+ M.unsafeWrite mv (q+2) bb++ colourValue !q !d+ | isNaN d = writeColour q (cm^.nanColour)+ | isInfinite d = writeColour q (if d < 0 then cm^.negInfColour else cm^.infColour)+ | otherwise = do let !o = 3 * (min 255 . max 0 . round $ (d - a) * m) M.unsafeWrite mv q (V.unsafeIndex cv o ) M.unsafeWrite mv (q+1) (V.unsafeIndex cv (o+1)) M.unsafeWrite mv (q+2) (V.unsafeIndex cv (o+2))++ go s i q+ | s == x-1 = do+ let d = V.unsafeIndex dv s+ colourValue q d return mv- -- go (s+1) (i+1) (q+3) | i == x = go (s - 2*x) 0 q | otherwise = do- let !d = V.unsafeIndex dv s- let !o = 3 * (min 255 . max 0 . round $ (d - a) * m)- M.unsafeWrite mv q (V.unsafeIndex cv o )- M.unsafeWrite mv (q+1) (V.unsafeIndex cv (o+1))- M.unsafeWrite mv (q+2) (V.unsafeIndex cv (o+2))+ let d = V.unsafeIndex dv s+ colourValue q d go (s+1) (i+1) (q+3) go (x * (y-1)) 0 0 @@ -268,8 +301,8 @@ let go i | i == 3*256 = return mv | otherwise = do- let PixelRGB8 r g b = cm ^. ixColour (fromIntegral i / (3*256))- . to colourToPixel+ let x = fromIntegral i / (3*256)+ RGB r g b = cm ^. ixColourR x . to toSRGB24 M.unsafeWrite mv i r M.unsafeWrite mv (i+1) g M.unsafeWrite mv (i+2) b@@ -277,10 +310,6 @@ go 0 -colourToPixel :: AlphaColour Double -> PixelRGB8-colourToPixel c = PixelRGB8 r g b- where RGB r g b = toSRGB24 (c `C.over` black)- -- | Render the heat map as a collection squares made up of 'Trail's. -- This method is compatible with all backends and should always look -- sharp. However it can become slow and large for large heat maps.@@ -306,12 +335,12 @@ -> QDiagram b V2 n Any pathHeatRender hm@(HeatMatrix _ _ a b) cm = ifoldMapOf hmPoints mk hm # lwO 0 where- normalise d = toRational $ (d - a) / (b - a)+ normalise d = (d - a) / (b - a) mk v@(V2 i j) d = rect w h # alignTR # translate (fromIntegral <$> v ^+^ 1)- # fcA (cm ^. ixColour (normalise d))+ # fc (cm ^. ixColour (normalise d)) where -- Squares that are not on the top left edge are slightly -- bigger to remove phantom gaps@@ -363,7 +392,7 @@ heatMapSize :: Functor f => LensLike' f a (V2 (N a)) heatMapSize = heatMapOptions . lens hSize (\s b -> (s {hSize = b})) - -- | The size of the full extend of the heat map.+ -- | The size of the full extent of the heat map. -- -- Default is extent of the heat matrix. heatMapExtent :: (Functor f, Fractional (N a)) => LensLike' f a (V2 (N a))
src/Plots/Types/Histogram.hs view
@@ -74,7 +74,7 @@ import Plots.Util --- | Construct a rectangle of size v with the bottom left at point p.+-- | Construct a rectangle of size $v$ with the bottom left at point $p$. rectBL :: (InSpace V2 n t, TrailLike t) => Point V2 n -> V2 n -> t rectBL p (V2 x y) = trailLike $ fromOffsets [V2 x 0, V2 0 y, V2 (-x) 0] # closeTrail `at` p@@ -96,7 +96,7 @@ instance OrderedField n => Enveloped (HistogramPlot n) where getEnvelope HistogramPlot {..} =- -- don't like this reduntent code+ -- don't like this redundant code getEnvelope . orient hOrient _reflectXY id . (id :: Path v n -> Path v n) $ ifoldMap drawBar hValues where
src/Plots/Types/Line.hs view
@@ -159,7 +159,7 @@ -- Trail and path ------------------------------------------------------------------------ --- | Construct a localed trail from a list of folable of points.+-- | Construct a localed trail from a list of foldable of points. mkTrail :: (PointLike v n p, OrderedField n, F.Foldable f) => f p -> Located (Trail v n) mkTrail = mkTrailOf folded
src/Plots/Types/Pie.hs view
@@ -27,6 +27,8 @@ -- -- <<diagrams/src_Plots_Types_Pie_piePlotExample.svg#diagram=piePlotExample&height=350>> --+-- (see 'piePlot' example for code to make this plot)+-- ---------------------------------------------------------------------------- module Plots.Types.Pie@@ -64,7 +66,7 @@ ------------------------------------------------------------------------ -- | Contains information to draw a single wedge of a pie. It is not--- intended to be draw directly. Instead use 'piePlot.+-- intended to be drawn directly. Instead use 'piePlot'. data Wedge n = Wedge { sEndR :: n , sStartR :: n
src/Plots/Types/Scatter.hs view
@@ -25,6 +25,8 @@ -- -- <<diagrams/src_Plots_Types_Scatter_scatterExample.svg#diagram=scatterExample&height=350>> --+-- (see 'scatterPlot' example for code to make this plot)+-- ---------------------------------------------------------------------------- module Plots.Types.Scatter ( -- * Scatter plot@@ -273,8 +275,9 @@ -- | Add a 'ScatterPlot' to the 'AxisState' from a data set. -- -- @--- myaxis = r2Axis ~&--- scatterPlot data1+-- 'scatterPlot' :: [('Double', 'Double')] -> 'State' ('Plot' ('ScatterOptions' 'V2' 'Double' ('P2' 'Double')) b) () -> 'State' ('Axis' b 'V2' 'Double') ()+-- 'scatterPlot' :: ['V2' 'Double'] -> 'State' ('Plot' ('ScatterOptions' 'V2' 'Double' ('P2' 'Double')) b) () -> 'State' ('Axis' b 'V2' 'Double') ()+-- 'scatterPlot' :: ['P2' 'Double'] -> 'State' ('Plot' ('ScatterOptions' 'V2' 'Double' ('P2' 'Double')) b) () -> 'State' ('Axis' b 'V2' 'Double') () -- @ -- -- === __Example__@@ -309,6 +312,12 @@ -- | Version of 'scatterPlot' without any changes to the -- 'ScatterOptions'. --+-- @+-- 'scatterPlot'' :: [('Double', 'Double')] -> 'State' ('Axis' b 'V2' 'Double') ()+-- 'scatterPlot'' :: ['V2' 'Double'] -> 'State' ('Axis' b 'V2' 'Double') ()+-- 'scatterPlot'' :: ['P2' 'Double'] -> 'State' ('Axis' b 'V2' 'Double') ()+-- @+-- -- === __Example__ -- -- <<diagrams/src_Plots_Types_Scatter_scatterExample'.svg#diagram=scatterExample'&height=350>>@@ -371,6 +380,30 @@ -- | Scatter plots with extra numeric parameter. By default the extra -- parameter is the scale of the marker but this can be changed.+--+-- @+-- 'bubblePlot' :: [('Double', ('Double', 'Double'))] -> 'State' ('Plot' ('BubbleOptions' v n) b) () -> 'State' ('Axis' b 'V2' 'Double') ()+-- 'bubblePlot' :: [('Double', 'V2' 'Double')] -> 'State' ('Plot' ('BubbleOptions' v n) b) () -> 'State' ('Axis' b 'V2' 'Double') ()+-- 'bubblePlot' :: [('Double', 'P2' 'Double')] -> 'State' ('Plot' ('BubbleOptions' v n) b) () -> 'State' ('Axis' b 'V2' 'Double') ()+-- @+--+-- === __Example__+--+-- <<diagrams/src_Plots_Types_Scatter_bubbleExample.svg#diagram=bubbleExample&height=350>>+--+-- > import Plots+-- > myweights = [2, 1.3, 1.8, 0.7]+-- > mydata7 = zip myweights [(1,3), (2,5.5), (3.2, 6), (3.5, 6.1)]+-- > mydata8 = mydata7 & each._2._2 *~ 0.5 & each._1 *~ 0.5+-- > mydata9 = [(1, V2 1.2 2.7), (3, V2 2 5.1), (0.9, V2 3.2 2.6), (2, V2 3.5 5)]+--+-- > bubbleAxis :: Axis B V2 Double+-- > bubbleAxis = r2Axis &~ do+-- > bubblePlot mydata7 $ key "data 7"+-- > bubblePlot mydata8 $ key "data 8"+-- > bubblePlot mydata9 $ key "data 9"+--+-- > bubbleExample = renderAxis bubbleAxis bubblePlot :: (BaseSpace c ~ v, PointLike v n p,@@ -387,6 +420,12 @@ s -- | Simple version of 'bubblePlot' without any changes to the 'Plot'.+--+-- @+-- 'bubblePlot'' :: [('Double', ('Double', 'Double'))] -> 'State' ('Axis' b 'V2' 'Double') ()+-- 'bubblePlot'' :: [('Double', 'V2' 'Double')] -> 'State' ('Axis' b 'V2' 'Double') ()+-- @+-- bubblePlot' :: (v ~ BaseSpace c, PointLike v n p,