BlackEdder / ggplotd

Plotting library for the D programming library. The design is inspired by ggplot2 for R.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

geomLine is consumed during drawing

drug007 opened this issue · comments

import core.thread;

import ggplotd.ggplotd;
import ggplotd.geom;
import ggplotd.aes;
import ggplotd.gtk;

void main()
{
    const win_width = 1024;
    const win_height = 1024;

    const radius = 400.;

    auto line_aes11 = Aes!(double[], "x", double[], "y")( [ 0, radius*0.45 ], [ 0, radius*0.45]);
    auto line_aes22 = Aes!(double[], "x", double[], "y")( [ 300, radius*0.45 ], [ 210, radius*0.45]);

    auto gtkwin = new GTKWindow();

    auto tid = new Thread(() { gtkwin.run("plotcli", win_width, win_height); }).start(); 
    auto gg = GGPlotD();
    gg.put( geomLine(line_aes11) );
    gg.put( geomLine(line_aes22) );

    gg.save("figure1.png", win_width, win_height);
    gtkwin.draw( gg, win_width, win_height );
}

After programm running the file "figure1.png" contains the lines but the gtk window doesn't.

Can confirm. Also happens when just saving twice.

import ggplotd.ggplotd;
import ggplotd.geom;
import ggplotd.aes;

void main()
{
    const win_width = 1024;
    const win_height = 1024;

    const radius = 400.;

    auto line_aes11 = Aes!(double[], "x", double[], "y")( [ 0, radius*0.45 ], [ 0, radius*0.45]);
    auto line_aes22 = Aes!(double[], "x", double[], "y")( [ 300, radius*0.45 ], [ 210, radius*0.45]);

    auto gg = GGPlotD();
    gg.put( geomLine(line_aes11) );
    gg.put( geomLine(line_aes22) );

    gg.save("figure1.png", win_width, win_height);
    gg.save("figure2.png", win_width, win_height);
    //gg.save("figure3.png", win_width, win_height);
}

Probably related, saving a third time results in a assertion failure (presumably because of using an empty range).

Having had a quick look at it during lunch this is a confusing issue. First of all the save method is const, so should not be depleting any ranges. Even so I tried adding save at the places where geomRange is "consumed" and that does not seem to make any difference.

Some things to try to and debug this:

  • Write a test that checks whether geomRange gets "depleted"
    • While doing so we might as well replace geomRange by an appender type (for performance reasons)
  • Debug the error/crash when calling save three times.

Turns out that you can call delegates that edit local state from const methods. This is now solved in master, but I'm still pondering how to ensure this doesn't happen for other geom* functions.

As a reference, that this happened even though the method is const is caused by this bug in the d compiler:
https://issues.dlang.org/show_bug.cgi?id=1983