Skip to content

Instantly share code, notes, and snippets.

@ljubobratovicrelja
Last active June 19, 2016 18:51
Show Gist options
  • Save ljubobratovicrelja/98a84e00d09206583b68cecfa48a8a1e to your computer and use it in GitHub Desktop.
Save ljubobratovicrelja/98a84e00d09206583b68cecfa48a8a1e to your computer and use it in GitHub Desktop.
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