2014-07-23

Tworzenie wykresów naukowych w LaTeX-u za pomocą pgfplots, cz. 2

Trochę długo zbierałem się do napisania drugiego odcinka serii, ale w końcu powstał ;-)

Tym razem mam do pokazania dwa przykłady wykresów stworzonych za pomocą pgfplots. Na ich przykładzie chciałbym pokazać, jak za pomocą pgfplots wczytywać serie danych z pliku.

Przykład pierwszy:



I kod:

\begin{tikzpicture}[scale=1.5]
\begin{axis}[
title={Zależność rozpuszczalności NH$_4$NO$_3$ i AgNO$_3$ od temperatury},
title style={text width=16em,text centered},
xlabel={Temperatura [\textcelsius]},
ylabel={Rozpuszczalność [g/100~g wody]},
xmin=0,xmax=100,
ymin=0,ymax=900,
legend pos=north west,
ymajorgrids=true,grid style=dashed
]

\addplot[color=red,mark=*] table[x = temperatura,y = rozpuszczalność] {nh4no3.dat};
\addplot[color=blue,mark=square] table[x index = 0,y index = 1] {agno3.dat};

\legend{NH$_4$NO$_3$,AgNO$_3$}
\end{axis}
\end{tikzpicture}


Jak można zauważyć, wykres ten jest bardzo podobny do przykładu podanego w pierwszej części serii. Zasadnicze różnice są dwie. Pierwsza, drobna, to dodanie text centered do title style - odpowiada to za wypośrodkowanie tytułu wykresu. Druga zmiana, grubsza, to takie zdefiniowanie serii danych aby były one pobierane z plików. Służy do tego polecenie table o ogólnej składni:

table[definicja dziedziny, definicja przeciwdziedziny] {nazwa pliku}


W powyższym przykładzie zostały użyte dwa pliki różniące się nieco układem danych.
Plik nh4no3.dat wygląda następująco:

temperatura rozpuszczalność
0 118
10 150
20 192
30 242
40 297
50 344
60 421
70 499
80 580
90 740
100 871

natomiast plik agno3.dat następująco:

0 122
10 167
20 216
30 265
40 311
60 440
80 585
90 652
100 733

Jak widać plik agno3.dat zawiera tylko dane numeryczne, natomiast w pliku nh4no3.dat pierwszy wiersz zawiera etykiety serii danych. W powyższym przykładzie do serii X-ów i Y-ów zawartych w pliku nh4no3.dat odwołujemy się za pomocą etykiet. Natomiast dla pliku agno3.dat serię danych definiujemy odwołując się do numerów kolumn
table[x index = 0,y index = 1]
Pakiet pgfplots, podobnie jak informatycy ;-), liczy od zera, więc kolumna o indeksie 0 jest w rzeczywistości pierwszą kolumną, zaś kolumna o indeksie 1 - drugą.

Przykład drugi:

I kod:

\begin{tikzpicture}[scale=1.5]
\begin{axis}[width=25em,height=20em,
axis y line=left,axis x line=bottom,
xmin = 6.384,xmax = 6.412,ymin=0,ymax = 3.5,enlargelimits=true,
xlabel = {Energia/keV},
ylabel = {Intensywność [$\times$ 1000]},
x tick label style={/pgf/number format/.cd,fixed,fixed zerofill,precision=3}
]
\addplot[only marks,mark=o,mark color=black] table[x expr = 0.001 * \thisrowno{0},y expr = 0.001 * \thisrowno{1}] {fe.dat};
\node[coordinate,pin=above:{$K\alpha_2$}] at (axis cs:6.3905,1.77) {};
\node[coordinate,pin=left:{$K\alpha_1$}] at (axis cs:6.4025,3.45) {};
\end{axis}
\end{tikzpicture}


Plik fe.dat wygląda następująco:

6418.6237560348 42
6418.5255907944 38.6
6418.4274290235 37.3

plus dodatkowe 398 linijek.

W tym przykładzie nowości w kodzie jest dużo więcej. Po pierwsze - osie X i Y mają zwrot zaznaczony strzałką. Odpowiada za to para poleceń axis y line=left oraz axis x line=bottom (jak można się domyśleć, oś X została ustawiona na dole a oś Y po lewej stronie, ale w niektórych przypadkach lepsze są inne ustawienia). Po drugie - polecenie enlargelimits=true pozwala pakietowi pgfplots na nieznaczne zwiększenie zakresów X lub Y jeśli przez to wykres będzie lepiej wyglądał. Na powyższym przykładzie można zauważyć, że chociaż wszystkie wartości Y są większe od zera (ymin=0), to pomiędzy zerem na osi Y a wyrysowaną osią X jest trochę miejsca.

Następnie, polecenie x tick label style określa styl rysowania liczb przy osi X. W powyższym przykładzie zdefiniowany został format pokazywania liczb z dziedziny. Aby zmienić format liczb należy obowiązkowo podać /pgf/number format/.cd, a następnie po przecinku wypisać odpowiednie parametry. Użyte przeze mnie parametry formatowania liczb to:
  • fixed - stała liczba cyfr po przecinku
  • precision=3 - liczba cyfr po przecinku jest równa 3
  • fixed zerofill - stała liczba cyfr po przecinku będzie respektowana nawet jeśli po przecinku będzie mniej cyfr znaczących niż zdefiniowane 3 (np. liczba 1.3 zostanie wyświetlona jako 1.300)
Po więcej informacji na temat możliwych formatów liczb odsyłam do manuala pgfplotstable.

Następnie przejdźmy do definicji serii danych. W pliku fe.dat mam serię X podaną w elektronowoltach (eV), natomiast na wykresie chciałbym mieć kiloelektronowolty (keV) na osi X. Pozwalam zatem pakietowi pgfplots na przeliczenie danych w locie. Za owo przeliczenie odpowiada fragment kodu
x expr = 0.001 * \thisrowno{0}
który za serię X przyjmuje wartości pierwszej kolumny danych w pliku fe.dat, pomnożone przez 0,001. Ważniejsze elementy składowe to:
  • expr - niech seria X będzie pewnym wyrażeniem matematycznym (ang. expression);
  • \thisrowno{0} - dla danego przeliczanego wiersza serii X weź dane z pierwszej kolumny (znów liczymy od zera) pliku (czyli np. 47 wiersz serii X będzie wyliczony z 47 wiersza pierwszej kolumny w pliku); zamiast \thisrowno{numer kolumny} można użyć też \thisrow{nazwa etykiety kolumny}.
Podobnie pozwoliłem sobie przeskalować serię Y. Przy definicji serii danych można też zauważyć parametr only marks, czyli dane będą rysowane tylko przy użyciu markerów, bez linii między nimi (a więc "dyskretnie").

Zostały jeszcze do omówienia dodatkowe oznaczenia na wykresie, wskazujące na piki Kα1 i Kα2. Do ich zamieszczenia użyłem polecenie \node, które powinno być znane użytkownikom tikz/pgf. Ogólna składnia polecenia \node, które służy do zamieszczania treści w zdefiniowanym punkcie (węźle), jest następująca:

\node[parametry] at (koordynata X, koordynata Y) {treść węzła};

W powyższym przykładzie nie umieściłem jednak niczego w węźle, natomiast wykorzystałem współrzędne węzła do przypięcia obok "szpilki" (pin) z opisem. Parametr above/below/left/right określa oczywiście, ze szpilka ma być przypięta od góry/dołu/prawej strony/lewej strony węzła. Odnośnie współrzędnych - pgf domyślnie używa centymetrów w koordynatach węzłów, więc należy go przekonać aby używał współrzędnych związanych z osiami wykresu. Służy do tego parametr axis cs.

Tych którzy doczytali do końca (można się chwalić w komentarzach, a co tam ;-) zapraszam na trzeci odcinek serii o pgfplots, który ukaże się za jakiś czas.