Autorem poniższego opracowania jest dr Piotr A. Dybczyński z Instytutu Obserwatorium Astronomiczne UAM w Poznaniu. Większość tego tekstu to swobodne tłumaczenie fragmentów oryginalnej dokumentacji, opracowanej w języku angielskim przez autora biblioteki, Tima Pearsona. Autor wyraził zgodę zarówno na wykonanie tłumaczenia dowolnych fragmentów tej dokumentacji jak i jego upublicznienie. Oryginalna dokumentacja znajduje się pod adresem: http://www.astro.caltech.edu/~tjp/pgplot .
Skrócony podręcznik użycia biblioteki PGPLOT
Spis treści
- Wstęp
- Zaczynamy
- Trochę bardziej skomplikowany przykład
- Proste elementy graficzne
- Opis wybranych funkcji biblioteki PGPLOT
- Przykłady rysunków z moich prac
Wstęp
Biblioteka PGPLOT, opracowana została przez amerykańskiego astronoma pracującego na CALTECH-u, Timothy J. Pearsona. Pierwszym jej zastosowaniem były programy redukujące obserwacje astronomiczne, pisane na Wydziale Astronomii na CALTECH.
Napisana początkowo tylko dla FORTRAN-u obecnie może być również używana przez programistów piszących w języku C.
Głównym celem autora było stworzenie biblioteki pozwalającej programiście możliwie małym wysiłkiem na tworzenie oprogramowania generującego jako jeden z wyników grafikę nadającą się do celów prezentacyjnych i do publikacji naukowych. Zawiera zarówno "prymitywne" funkcje postawienia kropki czy narysowania odcinka jak i zaawansowane funkcje automatycznego tworzenia histogramów czy skomplikowanych wykresów i map.
Może to być oprogramowanie przeznaczone wyłącznie do tworzenia grafiki na bazie gotowych zbiorów danych, ale często stosuje się bibliotekę PGPLOT w skomplikowanych programach obliczeniowych lub redukcyjnych, gdy tworzona "na żywo", w czasie rachunków grafika pozwala na podgląd wyników obliczeń i ocenę ich poprawności.
Ostatnie zmiany autor wprowadził w roku 2001, publikując wersję 5.2.2. Wersja ta dostępna jest publicznie do wykorzystania niekomercyjnego.
W Debianie biblioteka występuje jako pakiet pgplot5. Zawiera on, oprócz samej biblioteki również pliki nagłówkowe i część dokumentacji, która trafia do katalogu /usr/share/doc/pgplot5. Pakiet zawiera też kilkanaście programów przykładowych w FORTRAN-ie i jeden w C.
Ja używam tej biblioteki od wielu lat w swoich programach w języku C. Praktycznie wszystkie ilustracje w moich pracach naukowych powstały dzięki niej. Również bardzo wiele moich programów obliczeniowych i symulacyjnych zawiera wyjście graficzne generowane w trakcie obliczeń, tak, że mogę śledzić ich przebieg.
Zaczynamy
Co musisz mieć i zrobić by móc napisać, skompilować i uruchomić (z sukcesem) swój pierwszy program generujący grafikę przy użyciu biblioteki PGPLOT.
Zakładam, że piszesz program w języku C, w środowisku Debian Linux.
Biblioteka (czyli pakiet pgplot5) musi być poprawnie zainstalowana w systemie. Oznacza to np., że plik nagłówkowy biblioteki, cpgplot.h jest w systemowym katalogu /usr/include/ i możemy wstawiać go w swoich programach dyrektywą preprocesora: #include<cpgplot.h> . Jeżeli w Twoim środowisku tak nie jest, znajdź ten plik ( find / -name cpgplot.h ), skopiuj do katalogu, w którym piszesz program i wstawiaj dyrektywą #include"cpgplot.h" .
Również same biblioteki muszą znaleźć się w znanym systemowi katalogu bibliotek (w Debianie /usr/lib/) dzięki czemu do kompilacji i zlinkowania programu, którego kod źródłowy zapisany jest w pliku obrazek.c wystarczy wykonać komendę:
gcc -Wall obrazek.c -o obrazek -lcpgplot -lpgplot -lpng -lz -lX11 -lm
Opcja "-lcpgplot" dołącza bibliotekę pozwalającą korzystać z fortranowskiej biblioteki w języku C, opcja "-lpgplot" dołącza właściwą, fortranowską bibliotekę, opcje "-lpng -lz"' są niezbędne, bo Debianowa wersja biblioteki domyślnie pozwala generować obrazki w formacie PNG, opcja "-lX11" dołącza bibliotekę pozwalającą na generowanie grafiki na ekranie (w systemie X-Window) a opcja "-lm" dołącza bibliotekę matematyczną. Ta ostatnia nie jest niezbędna, ale praktycznie bardzo często wykorzystywana.
Zanim wypróbujemy czy to działa, warto jeszcze ustawić trzy zmienne środowiskowe, które poprawiają moim zdaniem komfort pracy z biblioteką PGPLOT. Zakładając, że Twoim shell-em jest bash dopisz do pliku ".bash_profile" (lub ".profile" - zależy od wersji) takie cztery linie:
PGPLOT_DEV=/xwindow
PGPLOT_BACKGROUND=white
PGPLOT_FOREGROUND=black
export PGPLOT_DEV PGPLOT_BACKGROUND PGPLOT_FOREGROUND
Pierwsza powoduje, że domyślnym urządzeniem graficznym będzie okienko na ekranie, a druga i trzecia zamieniają domyślne kolory tła i atramentu. Może dlatego, że autor zaczynał od rysowania mapek nieba, domyślnym kolorem tła w bibliotece PGPLOT jest czarny a domyślnym atramentem biały. Nie jest to specjalnie wygodne do oglądania wykresów na ekranie, a jest wręcz "karalne" gdy próbujemy taki rysunek z czarnym tłem wydrukować...
Aby zmienne te zadziałały, trzeba po zapisaniu nowej wersji pliku ".bash_profile" wylogować się, a następnie zalogować powtórnie.
Zacznijmy od czegoś prostego
Napiszmy w edytorze taki programik:
#include <stdio.h>
int main(void)
{
int k;
float x,y; /* biblioteka pgplot wszędzie, gdzie używa
danych zmiennoprzecinkowych stosuje typ float */
k=cpgopen("?"); /* argument "?" powoduje, że zostaniemy zapytani,
na jakim urządzeniu realizować grafikę */
if(k!=1) {
puts("\ncpgopen error\n");
return 1; /* jeśli wskazanego urządzenia nie dało się
otworzyć nie mamy nic do roboty */
}
cpgenv(0,300,0,200,1,-1); /* tworzymy środowisko do rysowania,
współrzędna x (pozioma) będzie w zakresie (0,300)
współrzędna y (pionowa) będzie w zakresie (0,200)
obie współrzędne będą skalowane tak samo
a wokół obszaru rysowania wyprodukowana będzie
prostokątna ramka */
cpgmove(10,30); /* ustaw "pióro" na pozycję (10,30) bez rysowania */
cpgdraw(110,130); /* narysuj odcinek od pozycji bieżącej do (110,130) */
x=200; y=30;
cpgmove(x,y); /* ustaw "pióro" na pozycję (x,y) bez rysowania */
/* a teraz narysuj cztery odcinki, by powstał kwadrat */
cpgdraw(x+50,y);cpgdraw(x+50,y+50);cpgdraw(x,y+50);cpgdraw(x,y);
cpgclos(); /* koniec rysowania */
return 0;
}
Jeżeli zapiszemy ten tekst źródłowy (komentarze można sobie darować) w pliku: "obrazek.c" i wykonamy polecenie: "gcc -Wall obrazek.c -o obrazek -lcpgplot -lpgplot -lpng -lz -lX11 -lm" , to jeśli nie narobiliśmy błędów a środowisko jest poprawnie skonfigurowane powstanie na dysku wykonywalny plik o nazwie "obrazek".
Spróbujmy go wykonać poleceniem: "./obrazek"
W terminalu pojawi się komunikat: "Graphics device/type (? to see list, default /xwindow):" i jeśli klepniemy Enter wybierając urządzenie domyślne (/xwindow) pojawi się okienko a w nim rysunek, jak obok.
Jeśli klikniemy na pokazaną obok miniaturkę, zobaczymy obrazek w pełnej rozdzielczości. Jest to plik w formacie PNG, otrzymany po uruchomieniu tego samego programu "./obrazek" ale po wybraniu urządzenia "/PNG". Wersję postscriptową uzyskujemy podobnie, podając jako urządzenie "/PS".
Dwie uwagi:
- Komunikacja z programem odbywa się cały czas poprzez terminal tekstowy z którego program był uruchamiany. W chwili wywołania funkcji cpgclos() w tym terminalu pojawia się napis: "Type <RETURN> for next page: " i dopiero naciśnięcie Enter zwija okno z rysunkiem. Zwykłe próby jego zamknięcia się nie powiodą.
- Przy pierwszym uruchamianiu programu wykorzystującego bibliotekę PGPLOT i generującego grafikę na ekranie pojawi się jeszcze jedno małe okienko, niekoniecznie widoczne na wierzchu. U mnie wygląda ono jak obok. Jest to okienko sygnalizujące, że działa "PGPLOT Server", czyli program generujący grafikę do X-Window. Możemy to okno zamykać ręcznie za każdym razem, ale nie ma takiej potrzeby. W gruncie rzeczy może być stale widoczne, w niczym to nie przeszkadza.
A tu przykład programu
trochę bardziej skomplikowanego i bardziej astronomicznego .
Proste elementy graficzne
Zaliczamy do nich: linie, markery, teksty i figury. Wszystkie one są "obcinane" na krawędzi obszaru rysowania (ang. vieport). Jedynie teksty, często umieszczane jako opisy poza samym rysunkiem nie są obcinane. W przypadku markera, jest on rysowany jedynie gdy jego środek (punkt który zaznacza) mieści się w obszarze rysowania.
Linie
Funkcja cpgline(n,x[],y[]) służy do rysowania łamanej składającej się z jednego lub więcej (n) odcinków, o końcach w punktach (x[i],y[i]).
Jeszcze prostsze są funkcje cpgmove(x,y) i cpgdraw(p,q). Pierwsza przesuwa "pisak" na pozycję (x,y) bez rysowania czegokolwiek a druga rysuje prosty odcinek od pozycji bieżącej pisaka do (p,q).
Zamiast:
cpgline(n,X,Y);
można więc napisać:
cpgmove(X[0],Y[0]);
for(i=1;i<n;++i) cpgdraw(X[i],Y[i]);
Markery
Służą do oznaczania punktów na rysunku różnymi symbolami, jak kropka, krzyżyk, kółko itp.
Funkcja cpgpt(n,x[],y[],symbol) rysuje serię markerów graficznych o kodzie symbol, w punktach o współrzędnych podanych w tablicach x[] i y[] typu (float!)
Funkcja cpgpt1(x,y,symbol) rysuje tylko jeden marker na pozycji (x,y).
Wśród markerów dostępne są między innymi kropki, wielokąty foremne, markery standardowe, symbole kodu ASCII oraz "symbole Hershey-a".
Więcej informacji w opisach funkcji cpgpt() i cpgpt1().
Teksty
Najprostsze funkcje tekstowe służą umieszczaniu na wykresie tytułu lub np. opisów osi. Taką rolę pełni funkcja cpgtext(x,y,"tekst"), wypisująca tekst od pozycji (x,y). Bardziej zaawansowaną kontrolę nad wypisywanym tekstem daje funkcja cpgptxt(). Można za jej pomocą pisać teksty pod kątem, np. pionowo, itd. Obie wymienione funkcje umieszczają tekst po podaniu współrzędnych (x,y) w dowolnym miejscu rysunku.
Do opisywania osi lub umieszczania tytułu nad wykresem lepiej nadają się funkcje umieszczające napisy wzgledem krawędzi wykresu. Są to funkcje cpgmtxt() i cpglab(). Ta ostatnia oczekuje po prostu trzech ciągów znaków, które umieszcza odpowiednio wypośrodkowane jako opis osi poziomej. pionowej i tytuł nad wykresem. Każdy z tych łańcychów może być pusty ("") i wtedy nie pojawia się na rysunku.
Sekwencje sterujące (ang. escape codes)
W tekstach przeznaczonych do wypisania wymienionymi wyżej funkcjami można stosować specjalne sekwencje sterujące.Uwaga! Ponieważ w języku C symbol '\' ma w ciągach znaków również znaczenie specjalne, w wszystkich poniższych przypadkach (poza '\\') trzeba backslasha użyć DWUKROTNIE!
Sekwencje te to:
- \u - zaczyna treść indeksu górnego
- \d - zaczyna treść indeksu dolnego lub kończy treść indeksu górnego. Kody \u i \d muszą być zawsze używane parami (w górę i z powrotem, lub w dół i z powrotem).
- \b - "backspace", czyli wypisz znak i cofnij kursor tekstowy na pozycje sprzed wypisania znaku. można w ten sposób próbować produkować "polskie literki", nakładając przecinek czy apostrof na literę łacińską. Efekt bywa różny.
- \fn, \fr, \fi i \fs - przełącza odpowiednio na czcionkę "Normal", "Roman" (z szeryfami), "Italic" (ukośną) i "Script" (pismo ręczne).
- \\ - znak "backslash" (ukośnik wsteczny)
- \x - ładny znak mnożenia (×)
- \. - centralna kropka (·)
- \A - symbol ångstöma (Å)
- \gx - litera grecka odpowiadająca x wg tabelki obok (kliknij by powiększyć).
- \mn lub \mnn - wypisuje marker standardowy o kodzie n lub nn.
- \(nnnn) - wypisuje "symbol Hershey-a" o kodzie nnnn.
Przykłady efektów uzyskanych z zastosowaniem funkcji tekstowych i kodów sterujących zawiera (klikalny) rysunek po lewej.
Jest to bitmapowa wersja postscriptowego rysunku z oryginalnej dokumentacji.
Figury
Proste figury geometryczne, wypełnione, zakreskowane lub puste zależnie od ustalonego atrybutu wypełniania (funkcja cpgsfs() ) możemy rysować funkcjami cpgrect() - prostokąt, cpgcirc() - koło lub okrąg i cpgpoly() - dowolny wielokąt, którego współrzędne x i y wierzchołków podajemy w odpowiednich tablicach (float!).
Opis wybranych funkcji biblioteki PGPLOT
Stopniowo dodaję tłumaczenia opisów następnych funkcji. Całość (oryginalna dokumentacja), po angielsku jest tu.
Moje przykładowe obrazki
Na tej stronie można pooglądać kilka przykładów obrazków generowanych przez moje programy.