Last active
June 19, 2016 18:51
-
-
Save ljubobratovicrelja/98a84e00d09206583b68cecfa48a8a1e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cairo : Surface, ImageSurface, Format; // modules from cairod package, to interface with ggplotd.GGPlotD.drawToSurface | |
import GtkSurface = cairo.Surface; // GtkD Surface ... | |
import GtkImageSurface = cairo.ImageSurface; // ... and ImageSurface to draw custom image to GtkD Window. | |
import ggplotd.ggplotd; | |
import ggplotd.geom; | |
import ggplotd.aes; | |
class Figure : Window | |
{ | |
DrawingArea drawArea; | |
// ... DrawingArea setup, and such GtkD setup. | |
void plot(const GGPlotD gg) | |
{ | |
auto w = drawArea.surface.getWidth(); | |
auto h = drawArea.surface.getHeight(); | |
ImageSurface surface = new ImageSurface(Format.CAIRO_FORMAT_RGB24, w, h); | |
surface = cast(ImageSurface) gg.drawToSurface(cast(Surface) surface, w, h); // error: (ref Surface surface, int width, int height) const is not callable using argument types (Surface, int, int) | |
auto drawSlice = drawArea.surface.getData().sliced(h, w, 4); | |
auto plotSlice = surface.getData().sliced(h, w, 4); | |
// overlay images | |
foreach (r; 0 .. h) | |
foreach (c; -0 .. w) | |
{ | |
auto plotAlpha = cast(float) plotSlice[r, c, 3] / 255.0f; | |
if (plotAlpha == 1.0f) | |
{ | |
drawSlice[r, c, 0 .. 3] = plotSlice[r, c, 0 .. 3]; | |
} | |
else | |
{ | |
foreach (channel; 0 .. cast(int) 3) | |
{ | |
drawSlice[r, c, channel] = cast(ubyte)((1.0f - plotAlpha) * drawSlice[r, | |
c, channel] + plotAlpha * plotSlice[r, c, channel]); | |
} | |
} | |
} | |
drawArea.queueDraw(); | |
} | |
} | |
auto examplePlot() | |
{ | |
import std.array : array; | |
import std.math : sqrt; | |
import std.algorithm : map; | |
import std.range : repeat, iota; | |
import std.random : uniform; | |
// Generate some noisy data with reducing width | |
auto f = (double x) { return x / (1 + x); }; | |
auto width = (double x) { return sqrt(0.1 / (1 + x)); }; | |
auto xs = iota(0, 10, 0.1).array; | |
auto ysfit = xs.map!((x) => f(x)).array; | |
auto ysnoise = xs.map!((x) => f(x) + uniform(-width(x), width(x))).array; | |
auto aes = Aes!(typeof(xs), "x", typeof(ysnoise), "y", string[], "colour")(xs, | |
ysnoise, ("a").repeat(xs.length).array); | |
auto gg = GGPlotD().put(geomPoint(aes)); | |
gg.put(geomLine(Aes!(typeof(xs), "x", typeof(ysfit), "y")(xs, ysfit))); | |
// | |
auto ys2fit = xs.map!((x) => 1 - f(x)).array; | |
auto ys2noise = xs.map!((x) => 1 - f(x) + uniform(-width(x), width(x))).array; | |
gg.put(geomLine(Aes!(typeof(xs), "x", typeof(ys2fit), "y")(xs, ys2fit))); | |
gg.put(geomPoint(Aes!(typeof(xs), "x", typeof(ys2noise), "y", string[], | |
"colour")(xs, ys2noise, ("b").repeat(xs.length).array))); | |
return gg; | |
} | |
void main(string[] args) | |
{ | |
Figure f = new Figure("My Awesome Image Window"); // create figure with given title | |
Image image = imread("image.png"); // load image from file system. | |
f.draw(image); // draw the image to figure | |
f.plot(examplePlot()); // add the plotting to the figure (GGPlotD) | |
f.show(); // show the figure on screen | |
waitKey(10_000); // wait for user key press, or given time in ms | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment