Verwendung von gnuplot i
Inhaltsverzeichnis
Grundlagen
Gnuplot_i ist ein C-Interface für das konsolenbasierente Programmpaket gnuplot. Letzteres ist ein verbreitetes und mächtiges Werkzeug um Zeichnen von Diagrammen (siehe http://www.gnuplot.info).
Gnuplot selbst ist für viele Platformen erhältlich, jedoch funktioniert Gnuplot_i nicht so ohne weiteres unter Windows, da es POSIX-Pipes verwendet.
Das Interface stellt einige Funktionen zur Verfügung, denen einfach (z.B. x,y-) Daten übergeben werden woraus ein Diagramm generiert wird. Um dem Programmierer weiteres die volle Gnuplot-Funktionalität zur Verfügung zu stellen ist die Möglichkeit gegeben Befehle direkt an Gnuplot zu "senden".
Weiteres existiert eine am ITP erweiterte Version des Interfaces, mit der u.A. auch 3D Plots erzeugt werden können.
Angenehme Eigenschaften
- Einfache Handhabung, man braucht nur wenige, gut dokumentierte Befehle zu kennen um wissenschaftlich korrekte Diagramme zu zeichnen.
- Die Syntax der Befehle erinnert sehr an Matlab
- Es handelt sich um ein sehr kleines, leicht einzubindendes Paket (ein c und ein h File)
Gnuplot und Windows Leider funktioniert dieses Interface nicht unter Windows. Jedoch existiert dafür eine Internetseite erweiterte Version. Notwendig ist natürlich auch eine vorhandene Gnuplot-Installation. Allerdings reicht ein Aufnehmen des Gnuplot-Verzeichnisses in die PATH-Umgebungsvariable nicht, sondern folgende Files müssen noch in jenen Ordner, in welchem die (eigene) Executable liegt, kopiert werden:
- wgnuplot.exe
pgnuplot.exe
Download
- Datei:Gnuplot i-ext-1.3.zip
- Erweiterte Version (von David Camhy und Georg Huhs)
- Wichtigste Erweiterungen:
- Titel kann direkt gesetzt werden
- Setzen des Plotranges
- Farbangaben beim Plotstil möglich
- Befehl zum Ausschalten der Legende
- 3D Plots (noch nicht ganz ausgereift)
- 2D Plots mit Fehlerbalken
- Datei:Gnuplot demo.zip
- Das weiter unten vorgestellte Demoprogramm
- Vorbereitet für die Verwendung mit Make, also zum Builden einfach im Verzeichnis make ausführen.
- Projektseite
- Hier kann die aktuellste Version heruntergeladen und die Doku online eingesehen werden. Weiteres sind Links zu anderen Gnuplot Interfaces angegeben.
- Homepage der Windows-tauglichen, erweiterten Version
- Datei:Gnuplot i-2.10.tar.gz
- In diesem Archiv befinden sich der ursprüngliche Sourcecode, zwei Testbeispiele und eine HTML-Dokumentation mit ausführlichen Beschreibungen der Funktionen. Achtung hierbei handelt es sich noch NICHT um die erweiterte Version und das kann zu den beschriebenen Problemen mit set_title() usw. kommen.
Programmierung
Einbinden der Library
Allgemeines zu diesem Thema gibt es unter hier nachzulesen.
Verwendet man Gnuplot_i so muss man mehrere c-Files und mindestens ein h-File managen. Die einfachste Variante ist, einfach die Datei gnuplot_i.c im Sourcefile zu inkludieren:
#include "gnuplot_i.c"
Diese inkludiert in weiterer Folge das h-File, sodass alle nötigen Deklarationen bereits eingebunden sind.
Wenn man berüchsichtigt, dass man eigentlich keine c-Files inkludieren soll, muss man etwas anders vorgehen, was hier allerdings zu ein wenig Mehraufwand führt. Da man die Gnuplot-Library selbst kaum ändern wird, reicht es aus sie einmal zu compilieren und dann stets mitzulinken. Weiteres wird statt des c-Files das h-File eingebunden.
$ g++ -c gnuplot_i.c
erzeugt das File gnuplot_i.o. Das Erzeugen der ausführbaren Datei erfolgt nun in zwei Schritten. Zuerst muss die Hauptdatei compiliert werden, dann werden die beiden Object(*.o)-Files gelinkt.
$ g++ -c <name_quellcode_file.c> $ g++ -o <name_executable> <name_quellcode_file.o> gnuplot_i.o
Diesen Vorgang kann man automatisieren indem man make verwendet. Ein sehr einfaches Makefile für das weiter unten angeführte Beispielprogramm würde so aussehen:
gnuplot_demo: gnuplot_i.o gnuplot_demo.o g++ -o gnuplot_demo gnuplot_i.o gnuplot_demo.o gnuplot_demo.o: gnuplot_demo.c \ gnuplot_i.h g++ -c gnuplot_demo.c gnuplot_i.o: gnuplot_i.c \ gnuplot_i.h g++ -c gnuplot_i.c all: gnuplot_demo clean: rm gnuplot_i.o gnuplot_demo.o gnuplot_demo
Die ausführbare Datei gnuplot_demo wird erzeugt, indem man einfach make in der Konsole eintippt (wenn das Makefile "Makefile" heißt). Zusätzlich kann man noch mit make clean alle unnötigen Dateien löschen lassen.
Prinzipieller Ablauf
- Starten einer Gnuplot-Session
- Einstellungen festlegen
- Daten plotten
- Beenden der Session (WICHTIG!)
Beispielprogramm
Der folgende Code ist ein Minimalstprogramm um eine korrekt beschriftetes Diagramm mit Titel und Legende zu generieren. Da die Funktion gnuplot_set_title() verwendet wird, funktioniert es allerdings nur mit der erweiterten Version von Gnuplot_i.
#include <math.h> #include "gnuplot_i.c" #define VECT_SIZE 100 int main(int argc, char *argv[]) { double x_vect[VECT_SIZE]; double y1_vect[VECT_SIZE]; double y2_vect[VECT_SIZE]; int vect_index; // Plotsession anlegen gnuplot_ctrl* gnp_handle; gnp_handle = gnuplot_init(); // Berechnung der Daten for (vect_index = 0; vect_index < VECT_SIZE; vect_index++) { x_vect[vect_index] = (double)vect_index/10.0; y1_vect[vect_index] = sin(x_vect[vect_index]); y2_vect[vect_index] = cos(x_vect[vect_index]); } // Voreinstellungen gnuplot_set_xlabel(gnp_handle, "x-Beschriftung"); gnuplot_set_ylabel(gnp_handle, "y-Beschriftung"); gnuplot_set_title(gnp_handle, "Kleines Gnuplot-Demo"); gnuplot_setstyle(gnp_handle, "lines"); // Plotten der Daten gnuplot_plot_xy(gnp_handle, x_vect, y1_vect, VECT_SIZE, "sin(x)"); gnuplot_plot_xy(gnp_handle, x_vect, y2_vect, VECT_SIZE, "cos(x)"); // Kurz warten sleep(10); // Session beenden gnuplot_close(gnp_handle); return 0; }
Erklärung der Funktionen
Die Funktionen sind durch ihre Benennung selbsterklärend. Jede Funktion erwartet einen Handle zu einer Gnuplot-Session. Damit können mehrere Sessions (Plotfenster) gleichzeitig bedient werden.
Mögliche Stile für die Funktion gnuplot_setstyle()
- lines
- points
- linespoints
- impulses
- dots
- steps
- errorbars
- boxes
- boxeserrorbars
Mit der letzten überarbeiteten Version können auch Farben mit dem Style angegeben werden. Dazu wird einfach hinter dem Style eine Farbangabe (die Gnuplot versteht) angehängt. Zum Beispiel lines 3 für rote Linien.
Neben den hier angeführten sind noch ein paar weitere Funktionen besonders erwähnenswert:
- void gnuplot_cmd(gnuplot_ctrl *handle, char *cmd, ...)
Damit kann ein beliebiger Befehl an Gnuplot gesendet werden. Somit stehen dem Programmierer alle Möglichkeiten von Gnuplot zur Verfügung. - void gnuplot_resetplot(gnuplot_ctrl *h)
Versetzt die Gnuplot-Session in den Startzustand zurück. ABER der Inhalt des Plotfensters wird damit nicht gelöscht, sondern erst beim nächsten Plotbefehl. - Weitere Plotfunktionen:
- void gnuplot_plot_x(gnuplot_ctrl *handle, double *d, int n, char *title)
2D Graph, wobei die x-Achse von 0 bis n-1 läuft - void gnuplot_plot_slope(gnuplot_ctrl *handle, double a, double b, char *title)
Zeichnet die Gerade [math]y = a \cdot x + b[/math] - void gnuplot_plot_equation(gnuplot_ctrl *h, char *equation, char *title)
Zeichnet eine Gleichung y = f(x), wobei im cString equation nur f(x) angegeben werden muss
- void gnuplot_plot_x(gnuplot_ctrl *handle, double *d, int n, char *title)
Verwendung mit nrutil
Wenn man für die Specherallozierung nrutil verwendet und 0 nicht der Startindex ist, kann man nicht einfach den von den nrutil-Funktionen gelieferten Pointer den Plotfunktionen übergeben. Es bieten sich mehrere Lösungsstrategien an:
- Pointerarithmetik
Es muss lediglich der Startindex zum Pointer dazugezählt werden - Verwenden der gnuplot_set_xrange() Funktion (und dem Analogon für y) - ist aber nur bei der erweiterten Gnuplot-Version verfügbar
- Errechnen des korrekten Pointers:
double *korrekt_ptr = &(data_array[startindex]);
wobei auf die runden Klammern auch verzichtet werden kann