1 /** 2 This module contains the different examples that are shown in the README 3 4 It will only be included in unittest code, but is empty otherwise. 5 */ 6 module example; 7 8 version (unittest) 9 10 import dunit.toolkit; 11 import std.stdio : writeln; 12 13 /// 14 unittest 15 { 16 /// http://blackedder.github.io/ggplotd/images/function.png 17 import std.random : uniform; 18 import std.typecons : Tuple; 19 import ggplotd.stat : statFunction; 20 import ggplotd.ggplotd : GGPlotD; 21 import ggplotd.geom : geomLine, geomPoint; 22 import ggplotd.range : mergeRange; 23 24 auto f = (double x) { return x / (1 + x); }; 25 26 auto aes = statFunction(f, 0.0, 10); 27 auto gg = GGPlotD().put(geomLine(aes)); 28 29 // Generate some noisy points 30 auto f2 = (double x) { return x / (1 + x) * uniform(0.75, 1.25); }; 31 auto aes2 = f2.statFunction(0.0, 10, 25); 32 33 // Show points in different colour 34 auto withColour = Tuple!(string, "colour")("aquamarine").mergeRange(aes2); 35 gg = gg.put(withColour.geomPoint); 36 37 gg.save("function.png"); 38 } 39 40 /// 41 unittest 42 { 43 /// http://blackedder.github.io/ggplotd/images/hist2D.svg 44 import std.array : array; 45 import std.algorithm : map; 46 import std.range : iota, zip; 47 import std.random : uniform; 48 49 import ggplotd.aes : aes; 50 import ggplotd.colour : colourGradient; 51 import ggplotd.colourspace : XYZ; 52 import ggplotd.geom : geomHist2D; 53 import ggplotd.ggplotd : GGPlotD, putIn; 54 import ggplotd.legend : continuousLegend; 55 56 auto xs = iota(0,500,1).map!((x) => uniform(0.0,5)+uniform(0.0,5)) 57 .array; 58 auto ys = iota(0,500,1).map!((y) => uniform(0.0,5)+uniform(0.0,5)) 59 .array; 60 auto gg = xs.zip(ys) 61 .map!((t) => aes!("x","y")(t[0], t[1])) 62 .geomHist2D.putIn(GGPlotD()); 63 // Use a different colour scheme 64 gg.put( colourGradient!XYZ( "white-cornflowerBlue-crimson" ) ); 65 66 gg.put(continuousLegend); 67 68 gg.save( "hist2D.svg" ); 69 } 70 71 /// 72 unittest 73 { 74 /// http://blackedder.github.io/ggplotd/images/filled_density.svg 75 import std.array : array; 76 import std.algorithm : map; 77 import std.range : repeat, iota, chain, zip; 78 import std.random : uniform; 79 80 import ggplotd.aes : aes; 81 import ggplotd.geom : geomDensity; 82 import ggplotd.ggplotd : GGPlotD, putIn; 83 import ggplotd.legend : discreteLegend; 84 auto xs = iota(0,50,1).map!((x) => uniform(0.0,5)+uniform(0.0,5)).array; 85 auto cols = "a".repeat(25).chain("b".repeat(25)); 86 auto gg = xs.zip(cols, 0.45.repeat(xs.length)) 87 .map!((a) => aes!("x", "colour", "fill")(a[0], a[1], a[2])) 88 .geomDensity 89 .putIn(GGPlotD()); 90 gg = discreteLegend.putIn(gg); 91 gg.save( "filled_density.svg" ); 92 } 93 94 /// 95 unittest 96 { 97 /// http://blackedder.github.io/ggplotd/images/density2D.png 98 import std.algorithm : map; 99 import std.range : iota, zip; 100 import std.random : uniform, Random, unpredictableSeed; 101 102 import ggplotd.aes : aes; 103 import ggplotd.colour : colourGradient; 104 import ggplotd.colourspace : XYZ; 105 import ggplotd.geom : geomDensity2D; 106 import ggplotd.ggplotd : GGPlotD, putIn; 107 import ggplotd.legend : continuousLegend; 108 109 // For debugging reasons, print out the current seed 110 import std.stdio : writeln; 111 auto rnd = Random(unpredictableSeed); 112 writeln("Random seed: ", rnd.front); 113 114 auto xs = iota(0,500,1).map!((x) => uniform(0.0,5, rnd)+uniform(0.0,5, rnd)); 115 auto ys = iota(0,500,1).map!((y) => uniform(0.5,1.5, rnd)+uniform(0.5,1.5, rnd)); 116 auto gg = zip(xs, ys) 117 .map!((a) => aes!("x","y")(a[0], a[1])) 118 .geomDensity2D 119 .putIn( GGPlotD() ); 120 // Use a different colour scheme 121 gg.put( colourGradient!XYZ( "white-cornflowerBlue-crimson" ) ); 122 gg.put(continuousLegend); 123 124 gg.save( "density2D.png" ); 125 } 126 127 /// 128 unittest 129 { 130 /// http://blackedder.github.io/ggplotd/images/labels.png 131 import std.algorithm : map; 132 import std.range : zip; 133 import std.math : PI; 134 135 import ggplotd.aes : aes; 136 import ggplotd.geom : geomPoint, geomLabel; 137 import ggplotd.ggplotd : GGPlotD; 138 import ggplotd.axes : xaxisRange, yaxisRange; 139 auto dt = zip( [0.0,1,2,3,4], [4.0,3,2,1,0], 140 ["center", "left", "right", "bottom", "top"], 141 [0.0, 0.0, 0.0, 0.0, 0.0], 142 ["center", "left", "right", "bottom", "top"]) 143 .map!((a) => aes!("x", "y", "label", "angle", "justify") 144 (a[0], a[1], a[2], a[3], a[4])); 145 146 auto gg = GGPlotD() 147 .put(geomPoint( dt )) 148 .put(geomLabel(dt)) 149 .put(xaxisRange(-2,11)) 150 .put(yaxisRange(-2,11)); 151 152 auto dt2 = zip( [1.0,2,3,4,5], [5.0,4,3,2,1], 153 ["center", "left", "right", "bottom", "top"], 154 [0.5*PI, 0.5*PI, 0.5*PI, 0.5*PI, 0.5*PI], 155 ["center", "left", "right", "bottom", "top"]) 156 .map!((a) => aes!("x", "y", "label", "angle", "justify") 157 (a[0], a[1], a[2], a[3], a[4])); 158 gg.put( geomLabel(dt2) ).put(geomPoint(dt2)); 159 160 auto dt3 = zip( [1.0,2,4,6,7], [8.0,7,5,3,2], 161 ["center", "left", "right", "bottom", "top"], 162 [0.25*PI, 0.25*PI, 0.25*PI, 0.25*PI, 0.25*PI], 163 ["center", "left", "right", "bottom", "top"]) 164 .map!((a) => aes!("x", "y", "label", "angle", "justify") 165 (a[0], a[1], a[2], a[3], a[4])); 166 gg.put( geomLabel(dt3) ).put(geomPoint(dt3)); 167 168 gg.save( "labels.png" ); 169 } 170 171 auto runMCMC() { 172 import std.algorithm : map; 173 import std.array : array; 174 import std.math : pow; 175 import std.range : iota; 176 import std.random : Random, unpredictableSeed; 177 178 // For debugging reasons, print out the current seed 179 import std.stdio : writeln; 180 auto rnd = Random(unpredictableSeed); 181 //auto rnd = Random(1193462362); // This is a seed that currently fails. Use it for debugging 182 writeln("Random seed MCMC: ", rnd.front); 183 184 import dstats.random : rNorm; 185 return iota(0,1000).map!((i) { 186 auto x = rNorm(1, 0.5, rnd); 187 auto y = rNorm(pow(x,3), 0.5, rnd); 188 auto z = rNorm(x + y, 0.5, rnd); 189 return [x, y, z]; 190 }).array; 191 } 192 193 /// 194 unittest 195 { 196 // http://blackedder.github.io/ggplotd/images/parameter_distribution.png 197 import std.algorithm : map; 198 import std.format : format; 199 import ggplotd.aes : aes; 200 import ggplotd.axes : xaxisLabel, yaxisLabel; 201 import ggplotd.geom : geomDensity, geomDensity2D; 202 import ggplotd.ggplotd : Facets, GGPlotD, putIn; 203 import ggplotd.colour : colourGradient; 204 import ggplotd.colourspace : XYZ; 205 206 // Running MCMC for a model that takes 3 parameters 207 // Will return 1000 posterior samples for the 3 parameters 208 // [[par1, par2, par3], ...] 209 auto samples = runMCMC(); 210 211 // Facets can be used for multiple subplots 212 Facets facets; 213 214 // Cycle over the parameters 215 foreach(i; 0..3) 216 { 217 foreach(j; 0..3) 218 { 219 auto gg = GGPlotD(); 220 221 gg = format("Parameter %s", i).xaxisLabel.putIn(gg); 222 if (i != j) 223 { 224 // Change the colourGradient used 225 gg = colourGradient!XYZ( "white-cornflowerBlue-crimson" ) 226 .putIn(gg); 227 gg = format("Parameter %s", j).yaxisLabel.putIn(gg); 228 gg = samples.map!((sample) => aes!("x", "y")(sample[i], sample[j])) 229 .geomDensity2D 230 .putIn(gg); 231 } else { 232 gg = "Density".yaxisLabel.putIn(gg); 233 gg = samples.map!((sample) => aes!("x", "y")(sample[i], sample[j])) 234 .geomDensity 235 .putIn(gg); 236 } 237 facets = gg.putIn(facets); 238 } 239 } 240 facets.save("parameter_distribution.png", 670, 670); 241 } 242 243 /// 244 unittest 245 { 246 // http://blackedder.github.io/ggplotd/images/diamonds.png 247 import std.csv : csvReader; import std.file : readText; 248 import std.algorithm : map; 249 import std.array : array; 250 import ggplotd.aes : aes; 251 import ggplotd.axes : xaxisLabel, yaxisLabel; 252 import ggplotd.ggplotd : GGPlotD, putIn; 253 import ggplotd.geom : geomPoint; 254 255 256 struct Diamond { 257 double carat; 258 string clarity; 259 double price; 260 } 261 262 // Read the data 263 auto diamonds = readText("test_files/diamonds.csv").csvReader!(Diamond)( 264 ["carat","clarity","price"]); 265 266 auto gg = diamonds.map!((diamond) => 267 // Map data to aesthetics (x, y and colour) 268 aes!("x", "y", "colour", "size")(diamond.carat, diamond.price, diamond.clarity, 0.8)) 269 .array 270 // Draw points 271 .geomPoint.putIn(GGPlotD()); 272 273 // Axis labels 274 gg = "Carat".xaxisLabel.putIn(gg); 275 gg = "Price".yaxisLabel.putIn(gg); 276 gg.save("diamonds.png"); 277 } 278 279 /// Multiple histograms examples 280 unittest 281 { 282 // http://blackedder.github.io/ggplotd/images/filled_hist.svg 283 import std.array : array; 284 import std.algorithm : map; 285 import std.range : repeat, iota, chain, zip; 286 import std.random : uniform; 287 288 import ggplotd.aes : aes; 289 import ggplotd.geom : geomHist; 290 import ggplotd.ggplotd : putIn, GGPlotD; 291 292 auto xs = iota(0,50,1).map!((x) => uniform(0.0,5)+uniform(0.0,5)).array; 293 auto cols = "a".repeat(25).chain("b".repeat(25)); 294 auto gg = xs.zip(cols) 295 .map!((a) => aes!("x", "colour", "fill")(a[0], a[1], 0.45)) 296 .geomHist 297 .putIn(GGPlotD()); 298 gg.save( "filled_hist.svg" ); 299 } 300 301 /// Size as third dimension 302 unittest 303 { 304 import std.range : zip; 305 import std.algorithm : map; 306 import ggplotd.aes : aes; 307 import ggplotd.geom : geomPoint; 308 import ggplotd.ggplotd : putIn, GGPlotD; 309 import ggplotd.axes : xaxisRange, yaxisRange; 310 311 auto gg = [0.0,1.0,2.0].zip([0.5, 0.25, 0.75], [1000, 10000, 50000]) 312 .map!((a) => aes!("x", "y", "size")(a[0], a[1], a[2])) 313 .geomPoint 314 .putIn(GGPlotD()); 315 gg.put(xaxisRange(-0.5, 2.5)); 316 gg.put(yaxisRange(0, 1)); 317 gg.save("sizeStore.png"); 318 } 319 320 /// Boxplot example 321 unittest 322 { 323 // http://blackedder.github.io/ggplotd/images/boxplot.svg 324 import std.array : array; 325 import std.algorithm : map; 326 import std.range : repeat, iota, chain, zip; 327 import std.random : uniform; 328 329 import ggplotd.aes : aes; 330 import ggplotd.geom : geomBox; 331 import ggplotd.ggplotd : GGPlotD, putIn; 332 333 auto xs = iota(0,50,1).map!((x) => uniform(0.0,5)+uniform(0.0,5)); 334 auto cols = "a".repeat(25).chain("b".repeat(25)); 335 auto gg = xs.zip(cols) 336 .map!((a) => aes!("x", "colour", "fill", "label" )(a[0], a[1], 0.45, a[1])) 337 .geomBox 338 .putIn(GGPlotD()); 339 gg.save( "boxplot.svg" ); 340 } 341 342 /// Changing axes details 343 unittest 344 { 345 // http://blackedder.github.io/ggplotd/images/axes.svg 346 import std.array : array; 347 import std.math : sqrt; 348 import std.algorithm : map; 349 import std.range : iota; 350 351 import ggplotd.aes : aes; 352 import ggplotd.axes : xaxisLabel, yaxisLabel, xaxisOffset, yaxisOffset, xaxisRange, yaxisRange; 353 import ggplotd.geom : geomLine; 354 import ggplotd.ggplotd : GGPlotD, putIn, Margins, title; 355 import ggplotd.stat : statFunction; 356 357 auto f = (double x) { return x/(1+x); }; 358 auto gg = statFunction(f, 0, 10.0) 359 .geomLine 360 .putIn(GGPlotD()); 361 362 // Setting range and label for xaxis 363 gg.put( xaxisRange( 0, 8 ) ).put( xaxisLabel( "My xlabel" ) ); 364 // Setting range and label for yaxis 365 gg.put( yaxisRange( 0, 2.0 ) ).put( yaxisLabel( "My ylabel" ) ); 366 367 // change offset 368 gg.put( xaxisOffset( 0.25 ) ).put( yaxisOffset( 0.5 ) ); 369 370 // Change Margins 371 gg.put( Margins( 60, 60, 40, 30 ) ); 372 373 // Set a title 374 gg.put( title( "And now for something completely different" ) ); 375 376 // Saving on a 500x300 pixel surface 377 gg.save( "axes.svg", 500, 300 ); 378 } 379 380 /// Example from the readme using aes and merge 381 unittest 382 { 383 import ggplotd.aes : aes, merge; 384 struct Data1 385 { 386 double value1 = 1.0; 387 double value2 = 2.0; 388 } 389 390 Data1 dat1; 391 392 // Merge to add a value 393 auto merged = aes!("x", "y")(dat1.value1, dat1.value2) 394 .merge( 395 aes!("colour")("a") 396 ); 397 assertEqual(merged.x, 1.0); 398 assertEqual(merged.colour, "a"); 399 400 // Merge to a second data struct 401 struct Data2 { string colour = "b"; } 402 Data2 dat2; 403 404 auto merged2 = aes!("x", "y")(dat1.value1, dat1.value2) 405 .merge( dat2 ); 406 assertEqual(merged2.x, 1.0); 407 assertEqual(merged2.colour, "b"); 408 409 // Overriding a field 410 auto merged3 = aes!("x", "y")(dat1.value1, dat1.value2) 411 .merge( 412 aes!("y")("a") 413 ); 414 assertEqual(merged3.y, "a"); 415 } 416 417 /// Polygon 418 unittest 419 { 420 import std.range : zip; 421 import std.algorithm : map; 422 import ggplotd.aes : aes; 423 import ggplotd.geom : geomPolygon; 424 import ggplotd.ggplotd : GGPlotD, putIn; 425 426 // http://blackedder.github.io/ggplotd/images/polygon.png 427 auto gg = zip([1, 0, 0.0], [1, 1, 0.0], [1, 0.1, 0]) 428 .map!((a) => aes!("x", "y", "colour")(a[0], a[1], a[2])) 429 .geomPolygon 430 .putIn(GGPlotD()); 431 gg.save( "polygon.png" ); 432 }