gnuplot – ‚lekkie’ narzędzie do wykresów (i nie tylko)

Opublikowany wcześniej tekst o badaniu stanu baterii w moim laptopie okrasiłem kilkoma wykresami. Do ich stworzenia mogłem  użyć dowolny pakiet biurowy – jak LibreOffice czy podobne. Zamiast tego postanowiłem jednak odświeżyć sobie narzędzie  gnuplot. Za jego pomocą można  w bardzo łatwy sposób tworzyć zaawansowane wykresy – bez konieczności instalacji ciężkiego oprogramowania. Wyniki eksportujemy do pliku graficznego – i rysunek to tekstu gotowy.

Tworzenie wykresów z gnuplot wygląda inaczej niż w przypadku pakietów biurowych. Zamiast klikać w Excelu – piszecie rodzaj skryptu w formie instrukcji (tekstowych) dla gnuplot. Skrypt i dane są wejściem dla narzędzia gnuplot. gnuplot przetwarza je i na jego wyjściu otrzymujecie gotowy wykres w wybranym formacie.

Instalacja

gnuplot dla Windows możecie pobrać ze strony projektu: sourceforge. Wybierzcie folder z najnowszą wersją. Zależnie od wersji Waszego systemu (32 lub 64 bity), pobierzcie plik „*mingw_1.exe”. Zainstalujcie i uruchomcie:

Dla linux, gnuplot najlepiej zainstalować z repozytorium Waszej dystrybucji. Na przykład dla Ubuntu:

Uruchomcie:

Jesteście teraz w powłoce narzędzia, co symbolizuje znak ‚zachęty’:

W tym tekście użyję wersji dla linux. Wersja dla Windows oferuje te same możliwości. Po prostu zamiast w terminalu – działacie w oknie z prostym emulatorem konsoli.

Przetwarzanie danych z pliku

Podczas analizy stanu baterii, prosty skrypt zapisywał dane o stanie baterii do pliku.

Każdy pomiar to osobna linia w pliku ‚battery_life.csv’. W każdej linii kolejne dane oddzielone są przecinkami:

gnuplot przyjmuję spację za domyślny znak dzielący kolejne dane w linijce pliku. U mnie są przecinki. Trzeba więc zmienić domyślne ustawienie ze spacji na przecinki, tak:

gnuplot traktuje rozdzielone dane jako kolumny. Kolumny liczą się od „1” (A nie od „0”) :

Na potrzeby wykresu interesuje  jedynie kolumna 2 (procent naładowania) i 3 (czas pozostały do rozładowania. Do zaznaczenia interesujących mnie kolumn służy słowo kluczowe „using”. Stworzę wykres dla baterii naładowanej od 10% do 100%:

Zauważcie, że:

  • plot: intrukcja kreślenia wykresów,
  • „plot [10:100]”: zawarte w nawiasach wartości to zakres, w jakim zmienna (x) będzie analizowana (oś pozioma). Możecie dodać ograniczenie dla zakresów na osiach x, y i z, np: [:][:][:]. Pozostawienie pustej wartości (np. [:10]) instruuje system do użycia wartości automatycznych. Zakresy muszą być podane bezpośrednio po słowie kluczowym plot;
  • „battery_life.csv”: źródło, z którego pobierane są dane; tutaj: plik o nazwie „battery_life.csv”. źródłem mogą też być oczywiście np. funkcje, przykład z sinusem:
  • using 2:3: użyj kolumn 2 i 3 dla osi x y; czyli na osi x wyświetlę procent naładowania baterii, a na y – czas…
  • title: tytuł wykresu.

Wykres przedstawia kolejne punkty pomiarowe. Wygląda… trochę mało intuicyjnie. Wprowadziłem pewne zmiany:

  • Oś x: czas rozładowania, oś y: procenty:
  • Zamiast pozostałego czasu pracy na baterii…. wziąłem numer linii wpisu ze stanem baterii (kolumna $0). W ten sposób stopień naładowania baterii porównuję do prawdziwego czasu pracy na baterii – a nie tego szacowanego przez system (kolumna 3). Mogłem tak zrobić, ponieważ kolejne wpisy o stanie baterii pojawiały się dokładnie co minutę (sekcja watch -n 60 w skrypcie):

Teraz:

Połączę jeszcze 2 wykresy – dla nowej baterii (plik: battery_life_new.csv) i dla starej (battery_life_new.csv):

Wynik:

To jeszcze może kolorki serii (instrukcja lc rgb):

I wynik:

Instrukcje w pliku…

Zanim pójdziemy dalej, warto z trybu interaktywnego przejść na plikowy. Wszystkie instrukcje dla gnuplot zapisujemy w osobnym pliku tekstowym. Zamiast za każdym uruchomieniem je powtarzać, instruujemy gnuplot, żeby załadował je z pliku, na przykład ‚battery_life.plot’:

Sam plik wygląda teraz tak:

Linia trendu

Uzyskane wartości wydają się liniowe, ale są trochę rozrzucone. Zamiast samych danych – spróbujmy dopasować do nich linię trendu:

Program obliczył wartości parametrów funkcji trendu. Co ciekawe, zmienne a i b jak i funkcja fn(x) zostaną utworzone automatycznie i mogę użyć ich bezpośrednio na wykresie  – zamiast samych danych:

Mała uwaga – żeby wykres dobrze się przeskalował, konieczne jest dodanie zakresu [0:360]. To samo zrobię dla charakterystyki ‚starej’ baterii. W rezultacie mój plik z instrukcjami dla gnuplot wygląda tak:

Zauważcie, że danych z pliku używam jedynie do dopasowania funkcji trendu fn i fo. Wykres oparty jest na fn i fo.

Podsumowanie

Największą zaletą gnuplot jest dla mnie to, że pozwala na oddzielenie danych od sposobu ich prezentacji. Mamy dane, przepis na ich interpretację – resztę robi gnuplot. Takie podejście sprawdza się zwłaszcza w przypadku analizy dużej ilości danych danych. Doceni je każdy, kto choć raz miał arkusz kalkulacyjny z kilkunastoma tysiącami wartości.

Kolejnymi zaletami pakietu gnuplot jest jego niewielki rozmiar oraz dostępność na niemal wszystkich systemach operacyjnych. Co więcej, gnuplot to jedno z tych narzędzi, którego rozwój trwa już wiele lat (pierwsza wersja w 1986 roku!). Początkowo bardzo ograniczony, obecnie obfituje w bardzo wiele opcji. Na jego temat powstało już wiele książek a podobno stosowany jest w bardzo poważnych badaniach.

Oczywiście jego opanowanie wymaga trochę zachodu. Ale jak już się trochę poduczycie i przyzwyczaicie – jego obsługa stanie się bardzo naturalna.

Podyskutuj o tym  poście na facebook.


Więcej o gnuplot

Poniżej zamieszczam skrót najciekawszych opcji.

Generowanie danych do pliku

Bardzo ciekawą opcją jest możliwość generowania punktów wykresu do tablicy.

Zamiast wyświetlać dane na wykresie, gnuplot zapisze je w w pliku „mydata.dta”. Dane te będą miały postać:

Ostatni parametr:

  • i: punkt jest w zakresie,
  • o: poza zakresem,
  • u: niezdefiniowane.

Dane będą zapisywane do tablicy (pliku) dopóki nie wywołacie:

Przykładowo:

…wygeneruje plik ‚myrands.dat’, w którym znajdzie się 50 losowo wygenerowanych liczb. Ilość wygenerowanych liczb wyznaczana jest przez „sampling rate” – ilość próbek, na które gnuplot podzieli wskazany przedział x 0 – 9 (zaczynając od ‚0’ a kończąc na ‚9’). W pliku znajdziecie 3 kolumny, typu:

Pierwsza kolumna zawiera wartość „x”, druga „y” a trzecia – wskaźnik zakresu. Instrukcja rand generuje liczbę losową (zmiannoprzeczinkową) w zakresie 0..1.

Wartość średnia

Generowanie wartości średniej dla zestawu danych:

Definiujemy tutaj funkcję, która jest stała (podobnie jak np. f(x)=3). Wywołujemy „fit”, która dopasowuje zmienną ‚srednia’ do zbioru danych w pliku ‚myrands.dat’ zgodnie z funkcją f(x).

Ostatnia z instrukcji tworzy wykres punktów oraz średniej – jako linii pogrubionej do 10 pikseli i opisanej w legendzie jako ‚Srednia’:

Wartość „srednia” możecie podglądnąć za pomocą instrukcji „print”:

Puste linie w pliku danych

gnuplot interpretuje puste linie w pliku z danymi:

  • pojedyncza linia: brak ciągłości danych
  • podwójna pusta linia (albo pusta linia i komentarz): nowy zestaw danych.

Do przesuwania się po zestawach danych służy słowo kluczowe „index” – do użycia np.  w plot.

‚Wygładzanie’ danych (smooth)

Słówko smooth ‚wygładza’ dane na wykresie.

Przykładowo zestaw:

Pomogę sobie ze skalowaniem osi:

Hmmm… te krzyżyki są mało widoczne, zmienię je i powiększę:

  • pt: pointtype, typ punktu, gdzie na przykład: krzyżyki: typ 1, kwadraty puste: typ 4, kwadraty pełne: typ 5, kółka puste: typ 6: kółka pełne: typ 7, trójkąty: 9 itp.
  • ps: pointsize, rozmiar punktu

Teraz użyję pełne kółka, trochę większe niż standard:

Wracając do samego uniq:

Jeżeli znajdą się dwie linijki odnoszące się do tej samej wartości na osi x, unique zamieni je na jeden wpis o wartości równej ich średniej. Stąd:

Na x=2′ mieliśmy y=3,5,10; ich średnia to 18/3=6 – co widać na wykresie.

 frequency sortuje podobnie – ale zamiast średniej, sumuje wartości y. W ten sposób możecie np. tworzyć histogramy.

Zauważcie, że przedefiniowałem zakres osi ‚y’. Równie dobrze możecie to pozostawić automatowi:

gnuplot> plot ‚data1.dat’ smooth frequency pt 7 ps 2

„Ukryte” kolumny

Dzielenie danych w pliku powoduje powstanie kolumn z danymi. Kolumny odlicza się od „1”. Możecie tworzyć wyrażeń z tymi kolumnami odwołując się do nich za pomocą $1, $2 itp.

Kolumna $0 to numer linii w aktualnym zestawie danych a $-2 (minus-dwa) – aktualny zestaw danych (index).

Różne terminale

Dla gnuplot terminal oznacza sposób, w jaki wyświetlane są dane. Dane mogą być:

  • wyświetlane na ekranie (terminal: wxt)
  • zapisywane w plikach graficznych – bitowych i wektorowych,
  • zapisywane w plikach przeznaczonych dla drukarek (PostScript)

Na przykład:

  • wxt: domyślny terminal wyświetlający dane na ekranie,
  • jpeg: wysyłanie danych do pliku jpeg,
  • pngcairo: wysyłanie danych to pliku png, np:
  • svg: wyjście w formacie grafiki wektorowej, np.:
  • postscript – pliki eps dla drukarek:
  • PDF:

Więcej o  fit

Wyniki dopasowania przez funkcję ‚fit’ powinny być uznane z wiarygodne, gdy współczynnik niepewności Asymptotic Standard Error są mniejsze niż 15% (tutaj).

Funkcja dopasowująca „fit” ustawia wartości kilku zmiennych, które możecie później użyć w obliczeniach:

  • FIT_WSSR: suma kwadratów odchyleń od funkcji dopasowanej za pomocą fit ( ang.  final sum of squares of residuals); w tym przypadku :
    FIT\_WSSR =\sum_{i=1}^{NSR+1} (y_i - f(x_i))^2
  • FIT_NDF: ilość „stopni swobody”, ilość punktów pomiarowych, efektywnie wielkość zbioru danych -1,
  • FIT_STDFIT, odchylenie standardowe funkcji dopasowanej od danych, gdzie:

Oczywiście celem algorytmu fit jest osiągnięcie jak najniższej WSSR.

Przykładowo, dla zbioru danych:

i stałej funkcji dopasowującej:

Wynik dopasowania:

Stąd, WSSR dla funkcji stałej, f(x) = srednia:

FIT_NDF ma wartość 3 (bo w serii było 4 pary liczb). Dla tego typu funkcji podanej do pasowania, FIT_WSSR będzie wartością średnią, a FIT_STDFIT – odchyleniem standardowym.

Oczywiście zauważcie, że funkcja fit, to:

Dopasowanie rozkładu normalnego

Rozkład normalny możecie dopasować za pomocą funkcji Gaussa:

Statystyka

gnuplot zawiera pakiet stat, który wspomaga obliczenia statystyczne, jak : średnia, odchylenie standardowe, suma, suma kwadratów, minimum, maksimum, medianę itp.

Podstawowe komendy
PolecenieOpisUwagi
set title 'title'Ustawia tytuł wykresu
set ylabel 'ylabel'
set xlabel 'xlabel'
'{/Symbol a}' dla literek greckich
set key
unset key
Włącza/ wyłącza wyświetlanie nazwy serii danych (skąd pochodzą dane na wykresie - prawy górny róg)Użyj 'title' z plot, żby ustawić nawę serii danych
set gridrysuje siatkę
set tics outUstawia
set xtics
set ytics
Ustawia podpisy na rzędnych/odciętych w siatce
plot Kreśli wykres
plot [:] [:] [:] ...Zakres osi x, y i z (automatyczny, jeżeli nie podano)Musi być umieszczony zaraz po słowie kluczowym 'plot'
index ::Wyznacza zestawy danych (w pliku oddzielone podwójnymi pustymi liniami) index 2:5:2 - drugi i czwarty zestaw danych
every ::::Pozwala na przeskakiwanie lini danych w pliku - np. gdy interesuje nas co drugi wiersz
using 2:3Wskazuje kolumny, w których są dane dla x:y:zUżywaj z 'plot' ; skrót: u
titleUstawia nazwę serii danychUżywaj z 'plot' ; musi być użyte po elemencie "using"
linecolor rgb ''Ustawia kolor wykresu Używaj z 'plot'; skrót: lc
linewidth Ustawia grubość liniiUżywaj z 'plot' ; skrót: lw
linetype 'typ_linii'Typ liniiSkrót: lt
pointtypeTyp punktuSkrót: pt
pointsizeWielkość punktuSkrót: ps
withUstawia styl wykresu; może być: lines (linie, bez zaznaczenia punktów danych), points, linespoints (punkty połączone liniami), impulses, dots, steps, fsteps, histeps, errorbars, xerrorbars, yerrorbars, xyerrorbars, boxes (słupki), boxerrorbars, boxxyerrorbars, financebars, candlesticks or vectorUżywaj z 'plot' . Skrót: w, Skróty:
- lines: l
- linespoints: lp
replotOdśwież wydruk
load "plik"Załaduj skrypt z komendami
set style data histogramsWykres histogramu
set terminal push
set terminal png
set output "graph.png"
replot
set terminal pop
Zapisz ustawienia terminala; ustaw typ wyjścia na "png", ustaw lik wyjściowy na 'graph.png' i wyślij do niego wykres. Na koniec przywróc ustawienia.

Źródła

  • https://www.youtube.com/watch?v=9k-l_ol9jok
  • http://www.gnuplot.info/docs_5.0/gnuplot.pdf
  • http://www-bs2.informatik.uni-tuebingen.de/services/nilse/books/GnuplotinAction.pdf
  • http://www.gnuplotting.org/
  • http://www.phyast.pitt.edu/~zov1/gnuplot/html/statistics.html
  • http://uft.edu.br/engambiental/prof/catalunha/arquivos/gnuplot/gnuplot_inaction.pdf
  • https://groups.google.com/forum/#!topic/comp.graphics.apps.gnuplot/uLSmHWK_xtE
  • http://www.ift.uni.wroc.pl/~zkoza/pu/gnuplot3.pdf
  • http://www.knf.ifd.uni.wroc.pl/materialy/gnuplot.pdf
  • http://home.agh.edu.pl/~gos/PI/wyklad_gnuplot.pdf
  • http://www.mif.pg.gda.pl/homepages/swinczew/KMM/gnuplot_podstawy.pdf
  • http://web.archive.org/web/20100726165306/http://t16web.lanl.gov/Kawano/gnuplot/index-e.html