2011-01-16 15 views
3

Ich bin gerade über Dan Stahlke gnuplot C++ I/O-Schnittstelle gekommen, die mich von "rollen meine eigenen" speichert. Leider gibt es nicht zu viele Beispiele und es gibt keine echte Dokumentation.Weitergabe von Daten aus C++ nach gnuplot Beispiel (mit Gnuplot-iostream-Schnittstelle)

Ich habe die Datentypen in meinem C++ Projekt:

struct Data 
{ 
    std::string datestr; // x axis value 
    float f1;    // y axis series 1 
    float f2;    // y axis series 2 
    float f3;    // y axis series 3 
}; 


typedef std::vector<Data> Dataset; 

ich einen Datensatz Variable von C++, übergeben werden soll, so dass ich die Daten (Daten auf der X-Achse dargestellt werden kann, und die 3 Zahlen aufgetragen als Zeitreihe auf der Y-Achse).

Kann mir jemand zeigen, wie man die Dataset-Variable von C++ nach gnuplot (unter Verwendung der Gnuplot-iostream-Schnittstelle) überträgt und ein einfaches Diagramm unter Verwendung der übergebenen Daten erstellt?

Antwort

1

Hatten Sie ein, die Beispiele betrachten, die mit gnuplot-Iostream kommen?

Sie sind etwas spärlich, aber sie zeigen, wie eine Handlung aus einer Reihe von Datenpunkten zu erstellen:

Gnuplot gp; 

gp << "set terminal png\n"; 

std::vector<double> y_pts; 
for(int i=0; i<1000; i++) { 
    double y = (i/500.0-1) * (i/500.0-1); 
    y_pts.push_back(y); 
} 

gp << "set output 'my_graph_1.png'\n"; 
gp << "plot '-' with lines, sin(x/200) with lines\n"; 
gp.send(y_pts); 
5

Ich habe vor kurzem eine neue Version zu git geschoben haben, die es einfach benutzerdefinierte Datentypen zu unterstützen, macht wie Dies. Um Ihre struct Data zu unterstützen, können Sie eine Spezialisierung der TextSender-Klasse bereitstellen. Hier ist ein vollständiges Beispiel, das die von Ihnen definierte Struktur verwendet.

 
#include <vector> 
#include "gnuplot-iostream.h" 

struct Data { 
    std::string datestr; // x axis value 
    float f1;    // y axis series 1 
    float f2;    // y axis series 2 
    float f3;    // y axis series 3 
}; 

typedef std::vector<Data> Dataset; 

namespace gnuplotio { 
    template<> 
    struct TextSender<Data> { 
     static void send(std::ostream &stream, const Data &v) { 
      TextSender<std::string>::send(stream, v.datestr); 
      stream << " "; 
      TextSender<float>::send(stream, v.f1); 
      stream << " "; 
      TextSender<float>::send(stream, v.f2); 
      stream << " "; 
      TextSender<float>::send(stream, v.f3); 

      // This works too, but the longer version above gives 
      // gnuplot-iostream a chance to format the numbers itself (such as 
      // using a platform-independent 'nan' string). 
      //stream << v.datestr << " " << v.f1 << " " << v.f2 << " " << v.f3; 
     } 
    }; 
} 

int main() { 
    Dataset x(2); 
    // The http://www.gnuplot.info/demo/timedat.html example uses a tab between 
    // date and time, but this doesn't seem to work (gnuplot interprets it as 
    // two columns). So I use a comma. 
    x[0].datestr = "01/02/2003,12:34"; 
    x[0].f1 = 1; 
    x[0].f2 = 2; 
    x[0].f3 = 3; 
    x[1].datestr = "02/04/2003,07:11"; 
    x[1].f1 = 10; 
    x[1].f2 = 20; 
    x[1].f3 = 30; 

    Gnuplot gp; 
    gp << "set timefmt \"%d/%m/%y,%H:%M\"\n"; 
    gp << "set xdata time\n"; 
    gp << "plot '-' using 1:2 with lines\n"; 
    gp.send1d(x); 

    return 0; 
} 

Eine ähnliche Sache kann getan werden, um das Senden der Daten in einem binären Format zu unterstützen. Ein Beispiel finden Sie unter example-data-1d.cc aus dem Git Repo.

Alternativ können benutzerdefinierte Datentypen wie diese durch Überschreiben operator<<(std::ostream &, ...) unterstützt werden.

Eine andere Option ist std::tuple (verfügbar in C++ 11) oder boost::tuple zu verwenden, anstatt eine eigene Struktur zu definieren. Diese werden standardmäßig unterstützt (nun, sie sind es, sie waren nicht zu der Zeit, als Sie die Frage gestellt haben).

Verwandte Themen