Search code examples
c++gnuplotgnuplot-iostream

Gnuplot not updating correctly even after reread


I am trying to plot two 3D objects that translate and rotate in gnuplot via gnuplot-iostream. In my .cpp file, I have a for-loop that goes for a 100 iterations. For each iteration the .dat files I wish to plot changes, so I'm expecting my plot to move.

I have set my gnuplot to persist so the plotting should "animate" through the 100 iterations, but for some reason, I get a really buggy result that moves twice (firstly with an incomplete version of the figures, then the second reflects the very last data that was written in the .dat files with the figures complete. It keeps that plot for the rest of the iterations).

I do not see the figures rotate/translate at all except for those two, and they are big jumps too. I should be able to see my figures traverse slowly through the space, but somehow it goes from midway to end. And every time I try to close the gnuplot window, it automatically opens a new one, maintaining the same plot. I would then need to close all of them over and over until there's no more to close.

Prior to this I had an animation going where I decided to just write all of the data in the file and plot it that way. But the problem was that it would plot every single translation/rotation of my figure from finish to end, so it looked like a huge blob of color all over the plot. Another problem is I want the plotting to correspond to specific math that is being executed in my program, so saving the plot for the end will not be useful visually.

At the moment I have something that looks like:

int main()
{
 Gnuplot gp;
 for(int i = 0; 1 < 100; i++)
    {
        // open 3dfigure.dat file
       // bunch of math
       ... 
       for(int j = 0; j < vector.size(); j++)
       {
          // more math 
           for(int k = 0; vector(j).size(); k++)
           {
               // write or overwrite 3dfigure.dat file
           } 
       } 
       gp<<"splot [-6:6] [-2:2] [-1:4] '3dfigure.dat' u 1:2:3 w lines \n"; 
       gp<<"pause 1 \n"; 
       gp<<"reread \n"; 
       // close 3dfigure.dat file
    } 
}

I've tried all sorts of arrangements on where to put the plotting code, I either get 100 iterations of the same looking plot, or I get an empty plot. I think there is a flaw with how I arranged my code (at first I figured well i'm rereading no changes so I'll put reread prior to splot... Didn't really work!)


Solution

  • So in order for me to plot my two figures' rotations and translations on the same window I had to completely change my approach. It turns out I didn't even need to use the whole Gnuplot gp(gnuplot -persist), nor did I need refresh, replot, reread, clear and etc.

    I used send1d to input my data instead of writing constantly to a file. I made two containers to hold the faces of my figures, both vectors of tuples. For example:

    std::vector<std::tuple<double,double,double>> faces1;
    std::vector<std::tuple<double,double,double>> faces2; 
    

    For every iteration, I push the faces into those containers (i.e. faces1.push_back(std::make_tuple(x,y,z));) and I plot this by doing the ff:

    gp<<"splot '-' u 1:2:3 w lines, '-' u 1:2:3 w lines \n"; 
    gp.send1d(face1); 
    gp<<"pause 0.5 \n"; 
    gp.send1d(face2);
    faces1.clear(); 
    faces2.clear(); 
    

    This works out for me because my plotting already happens within the for loop, so it is bound to update. IFor every iteration, we start with two empty vectors to fill with new data. Not clearing the vector will keep all of the previous data pushed back and you'll end up plotting every rotation/translation.

    Not sure if there is another to do it more efficiently, but this definitely solved my problems. I hope this helps someone who is dealing with something similar in the future.