In [1]:
from pylab import *
%matplotlib inline
from scipy.integrate import odeint
from mpl_toolkits.axes_grid1 import make_axes_locatable
from mpl_toolkits.mplot3d import Axes3D

# nastavitve za izris grafov (http://matplotlib.org/1.3.1/users/customizing.html)
rc('text', usetex=True)
rc('font', size=12, family='serif', serif=['Computer Modern'])
rc('xtick', labelsize='small')
rc('ytick', labelsize='small')
rc('legend', fontsize='medium')
rc('figure', figsize=(5, 3))
rc('lines', linewidth=2.0)
rc('axes', color_cycle=['k'])

Grafi II

Logaritemsko merilo

Linearno merilo, kot smo ga uporabljali doslej, ni vedno najbolje prilagojeno za prikaz podatkov. Kadar prikazujemo spremenljivko prek nekaj velikostnih redov, bodo male vrednosti stlačene v okolico izhodišča. Običajno zdravilo za ta problem je logaritemsko merilo. Včasih lahko s transformacijo merila napravimo graf, ki je blizu linearnemu in s tem optimalen za razbiranje vrednosti. Poglejmo si grafa podatkov iz datoteke adrenalin.dat v linearnem (levo) in v logaritemskem (desno) merilu.

In [2]:
podatki=loadtxt('../podatki/adrenalin.dat')

figure(figsize=(10,3))

subplot(121)
plot(podatki[:, 0], podatki[:, 1], 'ko', clip_on=False)
xlabel(r'Koncentracija adrenalina ($\mu$g/l)')
ylabel(r'$F/F_\textrm{max}$ (\%)')
yticks(linspace(0, 100, 5))
grid(alpha=0.5)
gca().tick_params(axis='x', pad=8)

subplot(122)
plot(podatki[:, 0], podatki[:, 1], 'ko', clip_on=False)
xscale('log')
xlabel(r'Koncentracija adrenalina ($\mu$g/l)')
ylabel(r'$F/F_\textrm{max}$ (\%)')
yticks(linspace(0, 100, 5))
grid(alpha=0.5)
gca().tick_params(axis='x', pad=8)

tight_layout()

Večdelni grafi

Velikokrat želimo prikazati odvisnost več različnih fizikalnih količin na enakem intervalu neke druge fizikalne količine. V takem primeru vsaka prikazana količina potrebuje svoje merilo. Dve merili lahko podamo ob levi in desni stranici okvira. Še raje pa (če je količin več, je to edina možnost) prikažemo vsako količino na svojem grafu tako, da so grafi poravnani en nad drugim. Grafe označimo npr. z (a), (b), (c), ..., da se potem lahko nanje sklicujemo v besedilu članka.

Velikokrat na istem grafu prikažemo obnašanje neke količine pri različnih vrednostih enega ali več parametrov. Pri tem uporabimo za vsako vrednost parametra drugačen tip črte (polna, črtkana, ...). V legendi navedemo vrednosti parametra in jih povežemo s tipom črte.

Prikažimo, kako se pri padanju telesa s časom spreminjajo pot \(s\), hitrost \(v\) in pospešek \(a\) pri različnih vrednostih parametra zračnega upora \(c\). Podatke izračunamo tako, da numerično rešimo diferencialno enačbo \(a=g-cv^2\).

In [3]:
t=linspace(0, 10, 1000)
y0=array([0, 0])
g=9.81
def podatki(c):
    def deriv(Y, t): 
        return array([Y[1], g - c * Y[1] ** 2])
    y=odeint(deriv, y0, t)
    return y[:, 0], y[:, 1], g - c * y[:, 1] ** 2  

s1, v1, a1=podatki(0)
s2, v2, a2=podatki(0.01)
s3, v3, a3=podatki(0.1)
In [4]:
figure(figsize=(5, 9))

ax=subplot(311)
plot(t, s1, t, s2, '--', t, s3, '-.');
ylabel(r'Pot (m)')
ax.xaxis.set_major_formatter(NullFormatter())
grid(alpha=0.5)
legend(('$c=0$', '$c=0.01\,\mathrm{m}^{-1}$', '$c=0.1\,\mathrm{m}^{-1}$'), loc=9, frameon=True)
annotate('(a)', xy=(0.03, 0.92), xycoords='axes fraction')

ax=subplot(312)
plot(t, v1, t, v2, '--', t, v3, '-.');
ylabel(r'Hitrost (m/s)')
ylim([0,115])
ax.xaxis.set_major_formatter(NullFormatter())
grid(alpha=0.5)
annotate('(b)', xy=(0.03, 0.92), xycoords='axes fraction')

subplot(313)
plot(t, a1, t, a2, '--', t, a3, '-.');
ylabel(r'Pospe\v sek (m/s$^2$)')
xlabel(r'\v Cas (s)')
ylim([0,11.5])
grid(alpha=0.5)
annotate('(c)', xy=(0.03, 0.92), xycoords='axes fraction')

subplots_adjust(hspace=0.05)

Namesto različnih vrst črt lahko uporabimo tudi barve. Barve so še posebej primerne, če prikazujemo graf količine pri več kot treh ali štirih različnih vrednostih parametrov.

In [5]:
figure(figsize=(5, 9))

ax=subplot(311)
plot(t, s1, t, s2, 'r', t, s3, 'b');
ylabel(r'Pot (m)')
ax.xaxis.set_major_formatter(NullFormatter())
grid(alpha=0.5)
legend(('$c=0$', '$c=0.01\,\mathrm{m}^{-1}$', '$c=0.1\,\mathrm{m}^{-1}$'), loc=9, frameon=True)
annotate('(a)', xy=(0.03, 0.92), xycoords='axes fraction')

ax=subplot(312)
plot(t, v1, t, v2, 'r', t, v3, 'b');
ylabel(r'Hitrost (m/s)')
ylim([0,115])
ax.xaxis.set_major_formatter(NullFormatter())
grid(alpha=0.5)
annotate('(b)', xy=(0.03, 0.92), xycoords='axes fraction')

subplot(313)
plot(t, a1, t, a2, 'r', t, a3, 'b');
ylabel(r'Pospe\v sek (m/s$^2$)')
xlabel(r'\v Cas (s)')
ylim([0,11.5])
grid(alpha=0.5)
annotate('(c)', xy=(0.03, 0.92), xycoords='axes fraction')

subplots_adjust(hspace=0.05)

Če na grafu prikažemo obnašanje neke količine pri velikem številu enakomerno razmaknjenih vrednosti parametra, so lahko vse črte enakega tipa. V tem primeru označimo obe skrajni vrednosti parametra, v opisni vrstici pod sliko pa navedemo, kakšen je korak med sosednjima vrednostima parametra. Zaradi preglednosti lahko črte tudi razmaknemo v navpični smeri, vendar le, kadar ni važna absolutna velikost, pač pa le medsebojna primerjava. Tudi v tem primeru pod sliko navedemo, za koliko smo razmaknili sosednji črti.

In [6]:
for c in linspace(0.01, 0.1, 10):
    s, v, a=podatki(c)
    plot(t, a, linewidth=1.0) 
xlabel(r'\v Cas (s)')
ylabel(r'Pospe\v sek (m/s$^2$)')
yscale('log')  
annotate(r'$c=0.01\,\mathrm{m}^{-1}$', xy=(7, 0.6), xytext=(0.75, 0.9), textcoords='axes fraction', arrowprops=dict(arrowstyle="->", relpos=(0, 1)));
annotate(r'$c=0.1\,\mathrm{m}^{-1}$', xy=(5, 0.0015), xytext=(0.3, 0.3), textcoords='axes fraction', arrowprops=dict(arrowstyle="->"));

Tridimenzionalni grafi

Včasih želimo z grafom prikazati, kako se neka fizikalna količina spreminja v odvisnosti od dveh drugih količin. Kot primer si poglejmo datoteko teren.dat, ki vsebuje podatke o nadmorski višini \(z\) v odvisnosti od koordinat \(x\) in \(y\).

In [7]:
teren=loadtxt('../podatki/teren.dat');
teren=teren.reshape((25, 25, 3));
x=teren[:, :, 0]
y=teren[:, :, 1]
z=teren[:, :, 2]

Uporabimo graf z barvno lestvico. Barvni trak ob grafu nam pove, katero nadmorsko višino predstavljajo posamezne barve.

In [8]:
fig=figure(figsize=(5, 5))
ax=fig.add_subplot(111, aspect='equal')
p=pcolor(x, y, z, cmap="RdBu_r", vmin=-0.5, vmax=0.5)
xlabel(r'$x$ (m)');
ylabel(r'$y$ (m)');
divider=make_axes_locatable(ax)
cax=divider.append_axes("right", size="5%", pad=0.1)
colorbar(p, cax=cax)
cax.set_ylabel(r'$z$ (m)');

Podatke lahko prikažemo tudi z izohipsami. Vsaki od izohips pripišemo ustrezno nadmorsko višino. V opisni vrstici pod grafom moramo navesti, v katera količina je prikazana na grafu in v katerih enotah so podane vrednosti na izohipsah.

In [9]:
fig=figure(figsize=(5, 5))
ax=fig.add_subplot(111, aspect='equal')
rc('contour', negative_linestyle='dashed')
p=contour(x, y, z, colors='k', linewidths=1.0)
xlabel(r'$x$ (m)');
ylabel(r'$y$ (m)');
clabel(p, inline=1, fmt='%.1f');
grid(alpha=0.5)

Lepa je kombinacija obeh pristopov:

In [10]:
fig=figure(figsize=(5, 5))
ax=fig.add_subplot(111, aspect='equal')
contourf(x, y, z, cmap="RdBu_r")
rc('contour', negative_linestyle='solid')
p=contour(x, y, z, colors='k', linewidths=1.0)
xlabel(r'$x$ (m)');
ylabel(r'$y$ (m)');
clabel(p, inline=1, fmt='%.1f');

Pravi tridimenzionalni grafi so zanimivi, saj omogočajo dobro kvalitativno predstavo o obnašanju prikazane količine, vendar iz njih težje razberemo vrednosti. Nekatera orodja omogočajo, da tak graf interaktivno vrtimo.

In [11]:
fig=figure(figsize=(6, 6))
ax=fig.add_subplot(111, projection='3d')
ax.plot_surface(x, y, z, rstride=1, cstride=1, linewidth=0.5, cmap="RdBu_r")
xlabel(r'$x$ (m)');
ylabel(r'$y$ (m)');
ax.set_zlabel(r'$z$ (m)');
ax.set_zlim([-0.3001,0.5]);

Naloge

  1. Prikaži podatke iz datoteke praznenjeKondenzatorja.txt v linearnem in logaritemskem merilu za napetost. Datoteka vsebuje meritev napetosti na kondenzatorju v voltih (drugi stolpec) v odvisnosti od časa v sekundah (prvi stolpec).

  2. V datoteki Maribor.zip so zbrani vremenski podatki z merilne postaje Maribor-letališče za obdobje od 1. 1. 1977 do 31. 1. 2015. Prikaži, kako so se v letu 2014 spreminjale dnevne vrednosti temperature (minimalne in maksimalne - obe nariši na istem grafu), oblačnosti in vlažnosti ter dnevna količina padavin. Ali lahko z vizualno primerjavo grafov opaziš kakšno povezavo med gibanji teh količin?

  3. Prikaži temperaturno polje v prečnem prerezu dimnika, kjer je temperatura vročih plinov \(200^{\circ}\mathrm{C}\), na zunanji steni pa je \(0^{\circ}\mathrm{C}\), iz podatkov v datoteki DIMNIK.DAT. V datoteki je območje temperatur normirano na interval \([0,1]\), podane so v mreži 24 x 24 točk. Napravi grafa z barvno lestvico in z risanjem izoterm.