2011-04-02

Tworzenie wykresów naukowych za pomocą GLE, cz. 1

Poniższy artykuł, mojego autorstwa, został po raz pierwszy opublikowany w 34 numerze czasopisma Dragonia Magazine. Ponieważ jest trochę długi, a dłuższe teksty internetowe ciężko się czyta, postanowiłem podzielić go na dwie części.

Czym jest GLE?


W ogólności - GLE (czyli Graphics Layout Engine) jest kompilowanym językiem skryptowym stworzonym do tworzenia wykresów i diagramów naukowych (lub też innych). Językiem kompilowanym, to znaczy że, tak jak np. w przypadku LaTeX-a, najpierw należy zakodować treść w pliku tekstowym z rozszerzeniem .gle, a następnie skompilować kod poleceniem

gle plik.gle

Jak na porządny program przystało, GLE posiada całe multum opcji (a zdecydowanej większości z nich oczywiścię nie opiszę). Jeśli chodzi o wykresy, to GLE potrafi tworzyć wykresy punktowe, liniowe, histogramy, wykresy konturowe i przestrzenne powierzchniowe, i tak dalej...
Stworzone wykresy możemy zapisać w formatach EPS (domyślnie), PS, JPEG, PNG oraz PDF.



Pierwszy wykres


Tyle tytułem wstępu. Przejdźmy do najważniejszego - czyli do tego jak zakodować nasz plik .gle, tak by otrzymać wykres. Oczywiście, aby stworzyć wykres potrzebujemy danych. Plik z danymi może na przykład wyglądać tak:

6687.220 9.76504397272977E-08 9.78813649595311E-08
6687.281 1.90105065780758E-10 1.87775675304024E-10
6688.185 5.57398934056191E-08 5.55462375296084E-08
6689.069 1.59020880677475E-09 1.59451932220722E-09

albo tak:

x x^2 x^3 x^4
1 1 1 1
2 4 8 16
3 9 27 81


Jak widzimy, w tym drugim przypadku pierwszy wiersz pliku z danymi zawiera opisy (etykiety) danych w poszczególnych kolumnach. Jak zmyślny czytelnik zauważy, zapisałem etykiety w notacji a'la LaTeX-owej, tyle że bez znaku dolara. Napisałem tak, ponieważ GLE potrafi wyciągać etykiety z pliku z danymi i zamieszczać je na wykresie. Zapiszmy zatem dane podane w drugim przykładzie jako test.dat oraz stwórzmy plik test.gle o następującej treści:


size 20 10
set hei .8
set font texcmr
begin graph
key pos tl
xtitle "Iksy"
ytitle "Igreki"
xaxis min 0 max 4 dticks 1 hei .5
yaxis min 0 max 10 dticks 2 hei .5
data test.dat d1=c1,c2
d1 line marker square color blue
end graph


i skompilujmy go poleceniem


gle test.gle


Stworzy się nam plik test.eps który będzie wyglądał mniej więcej tak:


Rysunek 1. Pierwsza wersja naszego wykresu.

Dobrze, mamy już obrazek, więc wypadałoby omówić poszczególne linie kodu. W pierwszej linii kodu zdefiniowaliśmy rozmiar obrazka (w centymetrach). I o ile dla grafiki wektorowej, czyli formatów EPS, PS i PDF, nie ma to większego znaczenia (bo są skalowalne bez utraty jakości), to dla formatów takich jak JPG i PNG już ma. Niekiedy trzeba więc zwiększyć rozdzielczość obrazka (co innego bowiem przyszykować wykres który będzie osadzony w publikacji na stronie A4, a co innego gdy będzie osadzony w plakacie o rozmiarze A0). Aby stworzyć obrazek w formacie PNG należy po prostu skompilować nasz plik test.gle z opcją -d, np.


gle -d png test.gle


Oczywiście zamiast PNG możemy używać także innych dozwolonych formatów. Możemy także nie zapisywać naszego obrazka do pliku, ale tylko podejrzeć go w oddzielnym oknie (GLE zachowuje się wtedy tak jak Gnuplot), używając opcji -d x11. Aby zmienić rozdzielczość tworzonego obrazka w formacie PNG lub JPG należy użyć opcji -r, np.


gle -d png -r 200 test.gle


W drugiej linii kodu ustaliliśmy domyślną wielkość czcionki na 0.8 (domyślną, bo dla każdego elementu wykresu można ustawić także wielkość czcionki). W linii trzeciej -- ustaliliśmy rodzaj czcionki. Texcmr, czyli Computer Modern Roman, to dość ,,normalna'' czcionka. Pełną listę dostępnych czcionek można znaleźć w Podręczniku Użytkownika GLE, dostępnym na stronie http://glx.sourceforge.net/.

Linie od czwartej do dwunastej to definicja naszego wykresu. Z czego, najważniejsze są linie dziesiąta i jedenasta, zaś linie czwarta i dwunasta to, jak można prosto zauważyć, polecenia otwierające i zamykające grupę kodu (w naszym wypadku jest to wykres). W linii piątej zdefiniowaliśmy połozenie legendy do naszego wykresu (polecenie key) na lewy, górny róg wykresu (polecenie pos tl). Oczywiście oprócz tl, czyli top left, możliwe są też położenia legendy w prawym, górnym rogu (polecenie tr), lewym, dolnym rogu (bl) oraz prawym, dolnym rogu (br) wykresu. Jak widzimy, opis naszych danych w legendzie został pobrany z pierwszego wiersza pliku z danymi. Linie szósta i siódma ustawiają nam opisy osi X i Y. Linie ósma i dziewiąta określają opcje osi X i Y takie jak: zakres osi (przez podanie wartośi minimalnej i maksymalnej), częstotliwość pojawiania się znaków podziałki na osi (np. dticks 2 oznacza, że duży znak podziałki będzie pojawiał się co dwie jednostki; możemy także używać opcji dsubticks aby ustawić częstotliwość pojawiania się małych znaków podziałki) oraz wielkość czcionki przy opisach osi (opcja hei).

Jak napisałem wcześniej, najważniejsze są linie dziesiąta i jedenasta. W linii dziesiatej definujemy plik z którego będą czerpane dane do naszego wykresu. W naszym przypadku jest to plik test.dat. Natomiast zapis d1=c1,c2 oznacza, że zdefiniowaliśmy pierwszą serię danych (oznaczoną d1) tak, że wartościami ,,x-ów'' będą dane z pierwszej kolumny (stąd c1) pliku test.dat, zaś wartościami ,,y-ów'' będą dane z drugiej kolumny pliku test.dat (stąd c2). Następnie, w linii jedenastej naszego kodu, określamy sposób rysowania wykresu. Tak więc seria danych d1 będzie zwizualizowana za pomocą linii (stąd line) oraz znaków kwadratu (stąd marker square), zaś wszystko będzie miało kolor niebieski (stąd color blue). Jeśli chodzi o rodzaje znaków oznaczajacych punkty na wykresie oraz dostępną paletę kolorów to wyszczególnienie podane jest w Podręczniku Użytkownika GLE. Dodam tylko, że najbardziej popularne symbole punktów to circle (okrąg), square (kwadrat), triangle (trójkąt), diamond (romb), oraz ich wypełnione odpowiedniki: fcircle, fsquare, ftriangle i fdiamond; a także dot (po prostu kropka) oraz cross (krzyżyk).

Poprawianie wykresu


Jeśli jednak spojrzymy na nasz wykres na Rys.1, to widzimy sporo mankamentów. Po pierwsze, kwadraty na wykresie są za duże; chcielibyśmy także mieć linię łączącą punkty wygładzona a nie kanciastą. Po drugie, legenda naszego wykresu nie jest zbyt estetyczna: znak kwadratu oraz znak linii występują obok siebie, a nie łacznie, czcionka w legendzie jest zbyt duża; przydałoby się też zlikwidować obramowanie. Poprawmy zatem nasz kod.


size 20 10
set hei .8
set font texcmr
begin graph
key pos tl compact nobox hei .6
xtitle "Iksy"
ytitle "Igreki"
xaxis min 0 max 4 dticks 1 hei .5
yaxis min 0 max 10 dticks 2 hei .5
data test.dat d1=c1,c2
d1 smooth line marker square msize 0.3 color blue
end graph


Po skompilowaniu powinniśmy dostać taki obrazek:


Rysunek 2. Druga wersja naszego wykresu.

Co zmieniliśmy? Po pierwsze, w linii piątej dodaliśmy polecenia compact, nobox oraz hei .6. Ostatnie z nich, jak łatwo się domyślić, zmienia wielkość czcionki w legendzie (wcześniej czcionka miałą domyślny, zdefiniowany w linii drugiej naszego kodu, rozmiar 0.8). Polecenie nobox zapewnia brak obramowania legendy. Natomiast polecenie compact pozbawia nas problemu z oddzielnym rysowaniem znaku kwadratu i znaku linii. Dalej idąc, w linii jedenastej przed poleceniem line dopisaliśmy smooth (co zapewnia nam wygładzanie linii), zaś za poleceniem marker square dodaliśmy msize 0.3 (co ustawia nam rozmiar symbolu punktu na 0.3 cm).

Więcej danych


Następnie spróbujmy umieścić wykres większej liczby serii danych niż tylko jedna. Do wykresu y=x2 dodajmy wykres funkcji y=x3 i y=x4.


size 20 10
set hei .8
set font texcmr
begin graph
key pos tl compact nobox hei .6 offset 1 1.5
xtitle "Iksy"
ytitle "Igreki"
xaxis min 0.5 max 3.5 dticks 1 hei .5
yaxis min 0 max 85 dticks 20 hei .5
data test.dat d1=c1,c2 d2=c1,c3 d3=c1,c4
d1 smooth line marker square msize 0.3 color blue
d2 smooth line marker square msize 0.3 color red
d3 smooth line marker square msize 0.3 color green
end graph



Rysunek 3. Trzecia wersja naszego wykresu.

Jak widać, w linii dziesiątej dodaliśmy dwie nowe serie danych pobieranych z pliku test.dat: serię danych oznaczoną d2 taką, że wartościami „x-ów'' będą dane z pierwszej kolumny pliku test.dat, zaś wartościami „y-ów'' będą dane z trzeciej kolumny pliku test.dat, oraz serię nazwana d3, dla której odpowiednio - „x-y'' to pierwsza kolumna z pliku z danymi, zaś „y-ki'' to czwarta kolumna. Serie te będą przedstawione na wykresie za pomocą kolorów czerwonego i zielonego. Aby wszystkie nasze punkty się zmieściły zmieniliśmy także zakres osi X i Y. Za pomocą polecenia offset 1 1.5 przesuneliśmy także legendę wykresu o 1 cm w prawo i 1.5 cm w dół.


Więcej tekstu


A teraz dodamy trochę więcej tekstu do naszego wykresu.


size 20 10
set hei .8
set font texcmr
begin graph
key pos tl compact nobox hei .6 offset 1 1.5
title "Wykres \Omega + \phi_{2,3}^4"
xtitle "Iksy"
ytitle "Igreki"
xaxis min 0.5 max 3.5 dticks 1 hei .5
yaxis min 0 max 85 dticks 20 hei .5
data test.dat d1=c1,c2 d2=c1,c3 d3=c1,c4
d1 smooth line marker square msize 0.3 color blue
d2 smooth line marker square msize 0.3 color red
d3 smooth line marker square msize 0.3 color green
end graph
amove 8 5
tex "$\sqrt[3]{x+2}$"
rmove 6 1
text abc



Rysunek 4. Czwarta wersja naszego wykresu.



W nowej wersji naszego wykresu (Rys. 4) dodaliśmy tytuł wykresu (szósta linia kodu) oraz dwa fragmenty tekstu na wykresie (linie 17-ta i 19-ta). Tytuł wykresu dodajemy oczywiście za pomocą polecenia title. Osobiście uważam, że tytuł wykresu naukowego nie powinien być zbyt rozbudowany - może go nawet nie być - ponieważ większość tresci powinno się podać w opisie pod wykresem. Jeżeli chodzi o tekst, to program GLE umożliwia wstawianie tekstu zwykłego, które posiada tylko podstawową funkcjonalność wstawiania wyrażeń matematycznych, oraz, dla bardziej skomplikowanych wyrażeń matematycznych, tryb TeX-owy. Tryb tekstu zwykłego obsługuje tylko podstawowe „komendy'' matematyczne, zapisywane w stylu a'la LaTeX-owym, takie jak: wstawianie indeksu dolnego (_{}) i górnego (^{}) oraz dużą liczbę znaków specjalnych (np. \alpha produkuje grecką literę α po pełną listę symboli odsyłam, jak zwykle, do podręcznika GLE). W trybie tym nie stworzymy jednak pierwiastka ani ułamka zwykłego. Do tego celu musimy użyć „pełnego'' trybu LaTeX-owego. Tryb ten aktywujemy za pomocą polecenia tex (tak jak w kodzie powyżej). Zwykłego trybu tekstowego bądź używamy do opisu etykiet osi, tytułów, bądź też, jeśli chcemy umieścić tekst na wykresie, możemy to zrobić za pomocą polecenia text.

Problem wstawiania tekstu na wykresie jest dobrym punktem wyjścia do przedstawienia dwóch poteżnych poleceń: amove i rmove. Oba służą do przeniesienia „uwagi programu GLE'' na punkt o zdefiniowanym przez nas położeniu: absolutnym, w przypadku polecenia amove, bądź względnym, w przypadku polecenia rmove. Zwróćmy uwagę na następujący fragment ostatniego kodu:


amove 8 5
tex "$\sqrt[3]{x+2}$"


Określa on przeniesienie sterowania na punkt o współrzędnych x = 8 cm i y = 5 cm względem początku naszego układu współrzędnych (w naszym przypadku punkt (0,0) to lewy-dolny róg obrazka), a następnie wypisanie wyrażenia w trybie TeX-owym.
Natomiast analogiczny fragment kodu:


rmove 6 1
text abc


określa przeniesienie sterowania na punkt położony o 6 cm w prawo i 1 cm do góry względem ostatniego zdefiniowanego obiektu (w naszym przypadku - względem wyrażenia definiowanego w poprzednich liniach w punkcie (8,5), a następnie wypisanie tekstu „abc''.


Rodzaje wykresów i style linii


Najwazniejsze typy wykresów to wykresy:

  • Punktowe - definiowane poprzez podanie komendy marker, np.

    d1 marker square msize 0.4 color red

  • Liniowe - definiowane poprzez podanie komendy line, np.

    d1 line color blue

  • Słupkowe - definiowane poprzez podanie komendy impulses, np.

    d1 impulses color green

Inne rodzaje wykresów, np. histogramy, pozwolę sobie pominąć.

We wcześniejszych sekcjach omówiłem pokrótce rodzaje markerów punktów. Teraz chciałbym opisać także sposoby personalizacji linii.
Dwa główne parametry linii na wykresie to jej grubość oraz styl. Grubość linii definiujemy za pomocą polecenia lwidth grubość-w-cm. Możemy zdefiniować albo grubość linii dla wszystkich linii na wykresie:

set lwidth 0.01

albo dla poszczególnej serii danych

d2 line lwidth 0.03 color blue

Polecenie lwidth 0, nie ustawia grubości linii na 0 cm, ale zmienia ją na domyślną grubość, czyli 0.02 cm.

Drugim ważnym parametrem linii jest jej styl. Styl linii definiujemy za pomocą polecenia lstyle kod-stylu, np.

set lstyle 1

lub

d3 line lstyle 3

Istnieje dziewieć predefiniowanych styli, onaczanych cyframi od 1 do 9. nazważniejsze z nich to: 1 - linia ciągła, 2 - linia kropkowana, 3 - linia przerywana. Kod 0 odpowiada domyślnemu stylowi linii, czyli linii ciągłej. Można tekże definiować własne style linii.