Ein Gnuplot-Tutorial

Gnuplot (Eigenschreibweise: gnuplot) ist ein skript– bzw. kommandozeilengesteuertes Computerprogramm zur grafischen Darstellung von Messdaten und mathematischen Funktionen (Funktionenplotter). Das Projekt Gnuplot wird seit 1986 kontinuierlich von einem internationalen Team ehrenamtlicher Entwickler vorangetrieben. Der Quellcode wird seit 2000 über SourceForge verwaltet.

Wikipedia (letzter Abruf: 04.08.2018)

Da die auf der offiziellen Projekt-Homepage verlinkten deutschsprachigen Tutorials allesamt auf eine Fehlerseite (404 – Page Not Found) führen, möchte ich hier ein eigenes Tutorial in deutscher Sprache anbieten. Darin werde ich zeigen, wie Messdaten aus Text- bzw. CSV-Dateien grafisch dargestellt und in den Formaten EPS, PNG und SVG ausgegeben werden können. Das Tutorial schließt mit einem Beispiel zur Histogramm-Erstellung.

Voraussetzungen

Um die Inhalte dieses Tutorials nachvollziehen zu können, benötigt Ihr eine gnuplot-Installation auf dem eigenen Rechner.

Benutzer von Linux können gnuplot für gewöhnlich über die Paketverwaltung ihrer Distribution installieren. Benutzer von Windows und anderer Betriebssysteme können unter gnuplot download nachschauen.

Die in diesem Tutorial verwendeten Beispiel-Dateien können direkt von dieser Seite heruntergeladen werden, um die Beispiele nachzuvollziehen.

Beispiel 1: Darstellung der Energiekostenentwicklung

Um dieses Beispiel nachvollziehen zu können, wird folgende Datei benötigt:

# Energiepreise_Heizoel_Strom.csv
# https://www.destatis.de/DE/Publikationen/Thematisch/Preise/Energiepreise/Energiepreisentwicklung.html
# Elektrischer Strom in Cent/kWh inkl. Steuern
# Leichtes Heizöl Cent/l inkl. Mineralölsteuer und Erdölbevorratungsbeitrag, ohne Mehrwertsteuer
# Jahresdurchschnitt
# Berichtsjahr;leichtes Heizöl;Strom
2000;35,30;
2001;32,06;
2002;30,27;
2003;30,75;
2004;34,41;
2005;45,11;
2006;50,32;
2007;49,73;
2008;64,08;21,72
2009;43,77;22,88
2010;54,87;24,07
2011;69,26;25,3
2012;75,33;26,36
2013;70,36;29,2
2014;64,37;29,78
2015;48,79;29,49
2016;40,94;29,73
2017;47,51;30,48
2018;53,74;

Das obige Listing zeigt den Inhalt der Datei Energiepreise_Heizoel_Strom.csv.

Die Datei enthält zu Beginn einige Kommentarzeilen (beginnend mit #) mit beschreibendem Text. Darunter befinden sich die drei Spalten Berichtsjahr, leichtes Heizöl und Strom, welche durch ein Semikolon voneinander getrennt sind. Diese Werte sollen nun in einem anschaulichen Diagramm dargestellt werden.

Daten mit gnuplot grafisch darstellen

Um die Daten aus obiger Datei grafisch darstellen zu können, sind zuerst folgende Schritte auszuführen:

  1. Öffne ein Terminal
  2. Wechsle in das Verzeichnis, in dem die Datei Energiepreise_Heizoel_Strom.csv liegt
  3. Starte gnuplot durch Eingabe des entsprechenden Kommandos
Bildschirmfoto vom Verzeichniswechsel und Start von gnuplot

Wir befinden uns jetzt im interaktiven Eingabemodus. Durch Eingabe der folgenden Befehle erhalten wir eine erste grafische Darstellung unserer Daten. Die gezeigten Befehle werden im Einzelnen nach der folgenden Abbildung erläutert.

Erster Plot des Diagramms
gnuplot> set datafile separator ";"
gnuplot> set autoscale
gnuplot> set xlabel "Jahr"
gnuplot> set ylabel "Preis in Cent"
gnuplot> plot "Energiepreise_Heizoel_Strom.csv" using 1:2 title "leichtes Heiz\U+FFC3\U+FFB6l Cent/l", "Energiepreise_Heizoel_Strom.csv" using 1:3 title "elektrischer Strom Cent/kWh"
gnuplot>

Das obige Listing stellt die Befehle zum Plot des Diagramms im Bild darüber dar.

In der ersten Zeile wird das verwendete Trennzeichen angegeben. In diesem Fall handelt es sich dabei um das Semikolon, welches die einzelnen Spalten in unserer CSV-Datei voneinander trennt.

Zeile 2 gibt an, dass sich Gnuplot selbst um eine sinnvolle Skalierung der Achsen im Diagramm kümmern soll. Wie man die Skalierung manuell vorgibt, wird in einem späteren Beispiel gezeigt. Mit `set xlabel/ylabel` wird die Achsenbeschriftung festgelegt.

In der letzten Zeile wird schließlich der Befehl zum Zeichnen des Diagramms eingegeben. Eingeleitet wird die Zeile vom Kommando „plot“, gefolgt von der Angabe des Dateinamens. Mit „using 1:2“ wird angegeben, dass Gnuplot die Spalten 1 und 2 aus der Datei darstellen soll. Dabei wird der erste Wert an der X-Achse und der zweite Wert an der Y-Achse abgetragen. Mit dem Schlüsselwort „title“ kann noch eine Graphenbeschriftung für die Legende vergeben werden. Nach dem Komma wird die Angabe wiederholt. Hier sollen die Daten der ersten und dritten Spalte aus der Datei visualisiert werden. Man könnte an dieser Stelle auch eine andere Datei angeben, aus der man Werte im Diagramm darstellen möchte. Dazu ist lediglich der entsprechende Dateiname zu ändern.

Selbstverständlich kann auch die Darstellungsform der Graphen beeinflusst werden. Das folgende Beispiel zeigt, wie man den Graphen für leichtes Heizöl als Linie und den für elektrischen Strom als Linie mit Punkten darstellt.

gnuplot> plot "Energiepreise_Heizoel_Strom.csv" using 1:2 with lines title "leichtes Heizl Cent/l", "Energiepreise_Heizoel_Strom.csv" using 1:3 with linespoints title "elektrischer Strom Cent/kWh"
Diagramm mit Linie und Linienpunkten

Wie man im  Listing sieht, kann hinter dem Schlüsselwort „with“ der zu verwendende Linientyp angegeben werden. Um zu sehen, welche Darstellungsformen möglich sind, kann man die eingebaute Hilfe aufrufen, indem man z.B. `help with` eingibt.

Gnuplot-Hilfe für die Funktion „with“

Die Hilfe in Gnuplot ist sehr umfangreich und bietet neben umfassenden Informationen zu allen Kommandos, Funktionen und Schlüsselwörtern auch einige schöne Beispiele. An ihr erkennt man in meinen Augen den hohen Reifegrad dieses Programms. Eine derart gute Dokumentation sucht man bei vielen anderen Projekten leider noch vergebens.

Die Entwickler von Gnuplot haben auch an die Tippmuffel unter uns gedacht. So lässt sich die Schreibweise etlicher Funktionen in Gnuplot abkürzen. Die beiden Zeilen im folgenden Listing sind äquivalent und führen zur gleichen Ausgabe.

gnuplot> plot "Energiepreise_Heizoel_Strom.csv" using 1:2 with lines title "leichtes Heizl Cent/l", "Energiepreise_Heizoel_Strom.csv" using 1:3 with linespoints title "elektrischer Strom Cent/kWh"

gnuplot> plot "Energiepreise_Heizoel_Strom.csv" u 1:2 w lines t "leichtes Heizl Cent/l", "Energiepreise_Heizoel_Strom.csv" u 1:3 w lines t "elektrischer Strom Cent/kWh"

Einstellungen speichern

Um nun nicht jedes Mal, wenn man Gnuplot startet, alle Einstellungen erneut eintippen zu müssen, können diese gespeichert werden.

gnuplot> save "Energiepreise_Heizoel_Strom.gp"

Diese Einstellungen können nun in einer neuen Gnuplot-Konsole mit load "Energiepreise_Heizoel_Strom.gp"geladen werden. Das Diagramm wird dabei automatisch mit den gespeicherten Einstellungen gezeichnet.

Ausgabe in PNG, SVG und EPS

Gnuplot bietet die Möglichkeit, Diagramme in verschiedensten Formaten auszugeben. Dazu wird in der interaktiven Gnuplot-Konsole das entsprechende Ausgabe-Terminal definiert und anschließend das Diagramm gezeichnet. Das folgende Listing zeigt den Code für Ausgabe des obigen Diagramms als PNG, SVG und EPS. Die Ergebnisse der Ausgabe befinden sich im aktuellen Arbeitsverzeichnis auf eurem Endgerät.

gnuplot> set terminal pngcairo size 640,480 enhanced font 'Verdana,10'
Terminal type set to 'pngcairo'
Options are ' background "#ffffff" enhanced font "Verdana,10" fontscale 1.0 size 640, 480 '
gnuplot> set output 'Energiepreise.png'
gnuplot> replot

gnuplot> set terminal svg size 640,480 fname 'Verdana' fsize 10
Terminal type set to 'svg'
Options are 'size 640,480 fixed enhanced fname 'Verdana'  fsize 10 butt dashlength 1.0 '
gnuplot> set output 'Energiepreise.svg'
gnuplot> replot

gnuplot> set terminal postscript eps size 3.2,2.4 enhanced color font 'Helvetica,20' linewidth 2
Terminal type set to 'postscript'
Options are 'eps enhanced defaultplex \
   leveldefault color colortext \
   dashlength 1.0 linewidth 2.0 butt noclip \
   nobackground \
   palfuncparam 2000,0.003 \
   size 3.20in, 2.40in "Helvetica" 20  fontscale 1.0 '
gnuplot> set output 'Energiepreise.eps'
gnuplot> replot
gnuplot>

Die Größenangaben (size) können selbstverständlich den eigenen Bedürfnissen angepasst werden.

Ist die Postscript-Ausgabe für ein Dokument bestimmt, welches in schwarz-weiß gedruckt werden soll, empfiehlt sich folgende Terminal-Konfiguration. Gnuplot bereitet dabei die Darstellung der Graphen für den Schwarz-Weiß-Druck auf.

gnuplot> set terminal postscript eps size 3.2,2.4 monochrome font 'Helvetica,20' linewidth 2
Terminal type set to 'postscript'
Options are 'eps enhanced defaultplex \
   leveldefault monochrome colortext \
   dashlength 1.0 linewidth 2.0 butt noclip \
   nobackground \
   palfuncparam 2000,0.003 \
   size 3.20in, 2.40in "Helvetica" 20  fontscale 1.0 '
gnuplot> set output 'Energiepreise_sw.eps'gnuplot> replot

Beispiel 2: Darstellung einer Messreihe mit Zeitabtrag an der X-Achse

Dieses Beispiel setzt den Schwerpunkt bei der Abtragung von Datum und Uhrzeit an der X-Achse mit entsprechender Formatierung. Daneben wird gezeigt, wie man selbst die anzuzeigenden Intervalle an X- und Y-Achse konfiguriert.

Um dieses Beispiel nachvollziehen zu können, wird folgende Datei benötigt:

In der Datei befinden sich Messwerte von drei DHT22-Sensoren, welche Temperatur und Luftfeuchtigkeit messen können. Die Datei besteht aus insgesamt 3983 Zeilen und besitzt folgenden Aufbau:

$ head -n6 dht22data.csv 
#Date,Temp1,Humd1,Temp2,Humd2,Temp3,Humd3
2018-06-04T17:57:26,23.80,61.50,23.90,51.50,22.70,52.80
2018-06-04T18:02:26,23.80,61.60,23.90,51.50,22.70,52.80
2018-06-04T18:07:27,23.80,61.50,23.90,51.50,22.70,52.80
2018-06-04T18:12:27,23.80,61.60,23.90,51.50,22.70,52.80
2018-06-04T18:17:28,23.80,61.30,23.90,51.50,22.70,52.80

In der ersten Spalte findet sich ein Zeitstempel, gefolgt von den jeweiligen Messwerten der drei Sensoren. Als Spaltentrennzeichen wird in dieser Datei das Komma verwendet. Als Dezimaltrennzeichen findet der Punkt Verwendung.

Im zu erstellenden Diagramm sollen Datum und Uhrzeit auf der X-Achse abgetragen werden. Auf der Y-Achse sollen die Temperaturwerte der drei Sensoren dargestellt werden. Die Luftfeuchtigkeit bleibt in diesem Beispiel unberücksichtigt.

set datafile separator ","
set xdata time
set timefmt "%Y-%m-%dT%H:%M:%S"
set xrange [ "2018-06-04T17:57:26" : "2018-07-11T12:44:50" ]
set yrange [ 18:25 ]
set format x "%m-%d\n%H:%M"
plot "dht22data.csv" u 1:2 title "Sensor 1", "dht22data.csv" u 1:4 title "Sensor 2", "dht22data.csv" u 1:6 title "Sensor 3"

Im obigen Listing wird zuerst das Spaltentrennzeichen definiert. In der zweiten Zeile wird Gnuplot mitgeteilt, dass auf der X-Achse Datum und Zeit abgetragen werden soll. Hinweis: Intern rechnet Gnuplot ausschließlich in Sekunden.

Zeile 3 teilt Gnuplot mit, in welchem Format Datum und Uhrzeit in der Datei vorliegen. In Zeile 4 werden die Grenzen definiert. Für die Angabe wurde der erste und der letzte Zeitstempel aus der Beispieldatei verwendet.

Mit set yrange [ 18:25 ] wird ein Intervall für die Y-Achse definiert, welches für eine Temperaturkurve sinnvoll erscheint. Das Kommando set format x "%m-%d\n%H:%M" gibt an, wie Datum und Uhrzeit an der X-Achse dargestellt werden sollen. In diesem Beispiel sollen erst Monat und Tag und nach einem Zeilenumbruch Stunde und Minute dargestellt werden. Der letzte Befehl zeichnet dann das folgende Diagramm.

Darstellung der Messwerte für die Temperatur

In der grafischen Darstellung ist auf den ersten Blick zu erkennen, dass es eine Lücke in der Messreihe gibt. Hierbei handelt es sich nicht um einen Fehler. Es fand in dem Zeitraum tatsächlich keine Messung statt. Zoomt man nun in das Diagramm hinein, kann man sehen, dass die Werte an der X-Achse automatisch skaliert werden.

Beispiel 3: Zweite Y-Achse

Im vorangegangenen Beispiel wurden nur die Temperaturwerte aus der Beispieldatei betrachtet. In diesem Beispiel soll die von einem Sensor gemessene Temperatur an der Y-Achse (links) und die Luftfeuchtigkeit an einer zweiten Y-Achse (rechts) abgetragen werden. Aus Gründen der Übersichtlichkeit wird dabei nur ein Ausschnitt der Werte für den ersten Sensor dargestellt.

set datafile separator ","
set xdata time
set timefmt "%Y-%m-%dT%H:%M:%S"
set xrange [ "2018-06-04T17:57:26" : "2018-07-11T12:44:50" ]
set yrange [ 23:25 ]
set y2range [ 40:65 ]
set y2tic
set format x "%m-%d\n%H:%M"
plot "dht22data.csv" u 1:2 title "Temp 1" axes x1y1, "dht22data.csv" u 1:3 title "Humd 1" axes x1y2

Mit set y2range [ 40:65 ] wird ein Intervall für die zweite Y-Achse festgelegt und mit set y2tic die Beschriftung der Achse aktiviert. Die letzte Zeile stellt den Plot-Befehl dar. Hier ist zu erkennen, dass bei Verwendung von zwei Y-Achsen stets mit anzugeben ist, an welcher Achse ein Wert abgetragen werden soll.

Darstellung von Temperatur und Luftfeuchtigkeit in einem Diagramm

Beispiel 4: Erstellung eines Histogramms

In diesem Beispiel wird aus den Daten einer CSV-Datei ein Histogramm erstellt. Die Datei selbst hat folgenden Aufbau und kann wie gewohnt von dieser Seite heruntergeladen werden, um das Beispiel nachvollziehen zu können.

Datum,0-6 Uhr,6-12 Uhr,12-18 Uhr,18-24 Uhr
2018-07-17,2,4,6,4
2018-07-18,1,5,5,2
2018-07-19,0,8,4,3
2018-07-20,0,3,7,6

Das Komma wird als Spaltentrennzeichen verwendet. Die erste Zeile enthält Spaltenüberschriften, gefolgt von den darzustellenden Werten in den folgenden Zeilen.

In diesem Beispiel wird dargestellt, wie viele Ereignisse pro Tag und Zeitraum erfasst wurden. Das Ergebnis soll dann wie folgt aussehen.

Darstellung von einer Anzahl Ereignisse pro Tag und Zeitraum
set datafile separator ","
set grid
set key top right outside vertical autotitle columnhead
set xtics rotate by 90 right out nomirror
set ytics out
set style fill solid border -1
set boxwidth 0.5 relative
set title "Ereignisse pro Tag und Zeitraum"
set style data histograms
set style histogram rowstacked
plot for [col=2:5] 'file.csv' u col:xticlabels(1)

Zu Beginn wird das Spaltentrennzeichen definiert. Die folgende Angabe schaltet ein Gitternetz innerhalb des Histogramms ein. Dies dient der besseren Übersicht.

Die dritte Zeile im Quelltext gibt an, dass die erste Zeile in der Beispieldatei genutzt werden soll, um passende Spaltenüberschriften zu generieren und als vertikale Legende rechts außerhalb des Diagramms darzustellen. Möchte man dies nicht verwenden, ist die erste Zeile der Beispieldatei auszukommentieren, da Gnuplot andernfalls einen Fehler meldet.

Da ein Histogramm mit einer wachsenden Anzahl Balken erstellt wird, ist die Beschriftung der X-Achse (mit den Werten aus Spalte 1) etwas anzupassen. Der Code in Zeile 4 dreht die Bezeichner um 90° und richtet sie rechtsbündig am dazugehörigen Balken aus. Die drei folgenden Zeilen kümmern sich um die Formatierung der Y-Achse und das Aussehen der Balken bzw. der Boxen in den Balken. Spielen Sie ruhig mit den Werten, um zu sehen, wie sich Änderungen auf die Darstellung auswirken.

Mit set title wird das Diagramm mit einem Titel überschrieben.

In den beiden vorletzten Zeilen wird angegeben, dass ein Histogramm gezeichnet werden soll und das die Daten Zeilenweise verarbeitet werden. Dies bedeutet, dass die in einer Zeile enthaltenen Werte anschließend als Boxen in einem Balken dargestellt werden. Pro Zeile wird ein Balken gezeichnet.

Die letzte Zeile zeichnet dann das Histogramm. Durch for [col=2:5] wird angegeben, dass die Werte in den Spalten 2 bis 5 als Boxen in einem Balken dargestellt werden. Mit col:xticlabels(1) wird erreicht, dass ein Balken einem Datum aus Spalte 1 zugeordnet wird.

Natürlich können auch die Einstellungen aus diesem Beispiel mit load "dateiname.gp" gespeichert und später wiederverwendet werden.

Fazit

Ich selbst bin erst vor relativ kurzer Zeit auf Gnuplot aufmerksam geworden, doch möchte ich es heute nicht mehr missen.

Hat man sich erstmal an die Bedienung gewöhnt, lassen sich schnell und effizient anschauliche Diagramme produzieren, ohne eine Tabellenkalkulation bemühen zu müssen.

Ich hoffe, dieses kleine Gnuplot-Tutorial hat euch gefallen und konnte euer Interesse an einem schönen und leistungsstarken Werkzeug wecken.

2 Gedanken zu „Ein Gnuplot-Tutorial

  1. Daniel

    Ich habe gnuplot vor 16 Jahren verwendet. Aber warum heute gnuplot verwenden, wenn matplotlib (python data stack) so viel mehr Möglichkeiten und Komfort bietet?

    Antworten
    1. Jörg

      Hallo Daniel,

      da ich mir gnuplot und matplotlib beide nur kurz angesehen habe, kann ich beide Werkzeuge (noch) nicht umfassend bewerten.

      Um meine Anforderungen abzudecken, aus denen sich die drei Beispiele dieses Tutorials ableiten, war ich mit gnuplot deutlich schneller am Ziel.

      Deinem Kommentar entnehme ich, dass Du offenbar hinreichende Erfahrungen mit matplotlib hast. Hast Du Interesse an einem Gastartikel für diesen Blog, der die drei Beispiele mit matplotlib umsetzt?

      Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.