Verwendung von gnuplot i
Inhaltsverzeichnis
Grundlagen
Gnuplot_i ist ein C-Interface für das konsolenbasierte 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 weiters unter Windows, da es POSIX-Pipes verwendet.
Das Interface stellt einige Funtionen zur Verfügung, denen einfach (z.B. x,y-) Daten übergeben werden woraus ein Diagramm generiert wird. Um dem Programmierer weiters die volle Gnuplot-Funktionalität zur Verfügung zu stellen ist die Möglichkeit gegeben Befehle direkt an Gnuplot zu "senden".
Weiters 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)
Download
- Datei:Gnuplot i-2.10.tar.gz
- In dem Archiv befinden sich der Sourcecode, zwei Testbeispiele und eine HTML-Dokumentation mit ausführlichen Beschreibungen der Funktionen.
- Projektseite
- Hier kann die aktuellste Version heruntergeladen und die Doku online eingesehen werden. Weiters sind Links zu anderen Gnuplot Interfaces angegeben.
- Datei:Gnuplot i-ext-1.1.zip UPDATED - nun mit Dokumentation der neuen Funktionen
- Erweiterte Version (von David Camhy)
- Wichtigste Erweiterungen:
- Titel kann direkt gesetzt werden
- Setzen des Plotranges
- 3D Plots (noch nicht ganz ausgereift)
- 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.
Programmierung
Einbinden der Library
Allgemeines zu diesem Thema gibt's 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, so dass 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. Weiters 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
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