3.4. Crtanje grafova

3.4.1. 2D grafovi

Glavna naredba za crtanje 2D grafova je plot()

sage: plot(sin(x), (x,0,2*pi), figsize=[4,2])
../_images/cell_174_sage0.png

Za kombiniranje plotova može se kao prvi argument staviti lista funkcija ...

sage: plot([sin(x), log(x)], (x,0,2*pi), figsize=[4,2])
../_images/cell_323_sage0.png

... ali je bolje naprosto zbrajati grafove pojedinih funkcija, što nam onda daje kontrolu nad svojstvima pojedinih linija (boja, debljina, ...).

sage: P1 = plot(log(x), (x,0,2*pi))
sage: P2 = plot(sin(x), (x,0,2*pi), color='red', linestyle='--',
....:          thickness=3)
sage: (P1+P2).show(axes_labels=['x', 'f(x)'], frame=True, axes=False,
....:          fontsize=16)
../_images/cell_326_sage0.png

Premda to nije obavezno, gore je bilo logično svojstva pojedinih linija stavljati kao argumente funkcija plot(), a svojstva grafa kao cjeline u završni show(). Inače, korištenjem metode show() moguće je jednostavno ponovno iscrtavanje grafa uz promjenu nekih opcija:

sage: P.show(frame=False, axes=True, aspect_ratio=2, fontsize=9)
../_images/cell_340_sage0.png

Funkcija plot() sama određuje raspon vrijednosti ordinate pogodan za crtanje zadanih funkcija. Međutim, ukoliko funkcija ima singularitet u području crtanja, to ispada loše:

sage: plot(1/(1-x^2), (x,-2,2))
../_images/cell_330_sage0.png

Tada moramo eksplicitno ograničiti ordinatu opcijama ymin and ymax. (A može se i lijepo označiti položaj polova opcijom detect_poles.)

sage: plot(1/(1-x^2), (x,-2,2), detect_poles='show', ymin=-5, ymax=5)
../_images/cell_332_sage0.png

Grafove često želimo upotrijebiti i izvan Sage radnog lista, npr. u nekom članku ili prezentaciji. Eksportiranje grafova i drugih objekata postiže se uporabom funkcije save(). Format grafičke datoteke određen je ekstenzijom. Dopuštene ekstenzije su .png, .ps, .eps, .svg, and .sobj.

sage: P.save('/tmp/graf.png')

Zadatak 1

Pronađite ovu datoteku na disku i prikažite je pomoću nekog programa za pregledavanje slika. (Na Windowsima je potrebno pristupiti virtualnoj Linux mašini putem ssh protokola (winscp, putty, ...) spajanjem na adresu na koju se spaja i Windows WWW browser, uz user=sage, pass=sage. Ako to nije moguće naprosto spremite sliku klikom desnim gumbom miša na nju, pa “Save Image As ...”.)

Zadatak 2

Nacrtajte graf funkcije log(x) između x=0.5 i x=1.5 bez ikakvih oznaka, okvira i osi, dakle samo liniju.

Osim funkcija eksplicitno zadanih u obliku \(y=y(x)\) možemo crtati i funkcije zadane parametarski u obliku \(y=y(t)\), \(x=x(t)\). Npr:

sage: var('t')
t
sage: ff = (exp(cos(t)) - 2*cos(4*t) + sin(t/12)^5)
sage: parametric_plot((ff*cos(t), ff*sin(t)),
....:      (t, 0, 2*pi), fill=True, fillcolor='orange', figsize=[3,3])
../_images/cell_373_sage0.png

Za crtanje raznih potencijala i srodnih funkcija, zgodna je funkcija contour_plot():

sage: var('x y')
sage: contour_plot(x^2-y^2, (x,-3,3), (y,-3,3), labels=True,
....:    label_colors='red',contours=[0,2,3,6], cmap='jet', colorbar=True)
../_images/cell_376_sage0.png

Zadatak 3

Koristeći funkciju parametric_plot() i trigonometrijske funkcije nacrtajte kružnicu.

Za crtanje podataka organiziranih u listu parova \([[x_1, y_1], [x_2, y_2], \ldots ]\) rabimo list_plot():

sage: data = [[0,0], [1,0.8], [2, 0.9], [3, 0.2],[4, -0.7]]
sage: list_plot(data, pointsize=20, color='red', figsize=[4,2])
../_images/cell_354_sage0.png

Zadatak 4

Uočite da se funkcija fibBinet(x) iz prošlog odjeljka može izvrijedniti i za vrijednosti argumenta x koje nisu cjelobrojne. Nacrtajte graf te funkcije za -4 < x < 7 i superponirajte na njega (u drugoj boji) točke koje odgovaraju vrijednostima funkcije za pozitivne cjelobrojne argumente [(1, F_1), (2, F_2), ... (7, F_7)]. Naputak: plot(...) + list_plot(...).

Zadatak 5

Koristeći funkciju parametric_plot() i trigonometrijske funkcije nacrtajte kružnicu.

3.4.2. 3D grafovi

Za crtanje 3D grafova stoje na raspolaganju dvije softverske biblioteke:

  • JMOL (default) traži da rade Java appleti u browseru (na Linuxu samo Sun Java funkcionira - mogući problemi u F-26).
  • Tachyon - raytracing paket, radi bez Jave, nije moguć interaktivni rad s crtežom (okretanje mišem)
sage: y = var('y')
sage: P2 = plot3d(x^4+y^4, (x, -2, 2), (y, -2, 2)); P2.show()

Klik mišem na sliku omogućuje mijenjanje smjera gledanja i zumiranje kotačićem miša. Desni klik otvara izbornik. Za “pravi 3D doživljaj” stavite dvobojne naočale pa onda desni klik -> Style -> Stereographic ->...

Ukoliko nemate mogućnost prikazivanja Java appleta, koristite ‘tachyon’:

sage: P2.show(viewer='tachyon', figsize=[3,3])
../_images/cell_37_sage0.png
sage: L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color="lightblue", opacity=0.8)
sage: P = plot3d(lambda x,y: 4 - x^3 - y^2, (-2,2), (-2,2), color='green')
sage: Q = plot3d(lambda x,y: x^3 + y^2 - 4, (-2,2), (-2,2), color='orange')
sage: (L + P + Q).show(viewer='tachyon', figsize=[3,3])
../_images/cell_26_sage0.png

3.4.3. Matplotlib biblioteka

Dosad rečeno je dovoljno za osnovno skiciranje. Funkcija plot() i ostale navedene funkcije za 2D grafove su zapravo samo sučelje za tzv. matplotlib grafičku biblioteku. Za precizniju kontrolu nad crtanjem potrebno je izravno pozivati funkcije ove biblioteke.

Matplotlib zapravo ne crta funkcije tj. linije već samo liste točaka (slično kao list_plot() gore), pa se crtanje linija dobiva iscrtavanjem i spajanjem gustih skupova točaka. Za kreiranje ovih lista točaka možemo koristiti NumPy funkcije linspace() i logspace(). koristiti.

sage: import matplotlib.pyplot as plt
sage: import numpy as np

Elementarni primjer

sage: fig, ax = plt.subplots()
sage: xs = np.linspace(0, 2*np.pi)
sage: ax.plot(xs, sin(xs))
sage: fig.savefig('fig1')
../_images/sine.png

Par komentara:

  • Za komunikaciju s Matplotlib bibliotekom koristimo modul pyplot (kojeg smo preimenovali u plt) koji omogućuje nešto pristupačnije sučelje [1].
  • Kao granicu koristimo numeričku vrijednost za \(\pi\) iz NumPy biblioteke.
  • Funkcija plot.subplots stvara dva objekta: sliku (figure) i panel (axis). Složene slike mogu imati više panela, vidi primjer dolje.
  • U čistom Pythonu, komanda za prikazivanje slike bila bi fig.show(), ali u Sageu je za prikaz potrebno kreirati datoteku sa fig.savefig() koju onda Sage automatski prikaže u radnom listu [2].
  • Najvažnije: sintaksa Matplolibove funkcije plot traži kao prve argumente posebno listu x-koordinata, i posebno listu y-koordinata:

    ax.plot([x1, x2, ...], [y1, y2, ...], <opcionalni argumenti>)
    

    To je različito od srodne Sageove funkcije list_plot koja traži kao jedini argument listu parova koordinata:

    list_plot([[x1, y1], [x2, y2], ...], <opcionalni argumenti>)
    

    Za pretvorbu jedne vrste liste u druge, vidi zadatak na kraju odjeljka o NumPy listama.

sage: fig, (ax1, ax2) = plt.subplots(1, 2, sharey=True, figsize=[4,3])
sage: ax1.plot(xs, sin(xs))
sage: ax1.set_title('sinus')
sage: ax2.plot(xs, cos(xs), color='red', linestyle='--')
sage: ax2.set_title('kosinus')
sage: fig.savefig('fig1')
../_images/twoaxes.png
sage: xs = np.logspace(-2.0, 0.8, 100)  # granice su log_10(x)
sage: fig, ax = plt.subplots(figsize=[7,4])   # specifikacija dimenzija
sage: ax.plot(xs, sin(xs), color='red', linestyle='--',
....:                              label='$\sin(x)$')  # LaTeX oznake
sage: ax.plot(xs, sqrt(xs),
....:   'b-', label='$\sqrt{x}$')  # skraćene oznake za boju i tip linije
sage: ax.set_xscale('log')
sage: ax.axhline(0, color='g', linewidth=1)  # horizontalna linija na y=0
sage: ax.set_xlabel('x', fontsize=14)
sage: ax.set_ylabel('f(x)', fontsize=14)
sage: ax.legend(loc="upper left")
sage: fig.tight_layout()   # inače se ne vide cijele oznake na osima
sage: fig.savefig('test')
../_images/logx.png

Zadatak 6

Nacrtajte (Matplotlibom) 100 slučajno raspoređenih točaka (hint: np.random.rand(), te ax.plot(..., linestyle='None', marker='o')) gdje su x i y koordinate tih točaka u intervalu (-1,1), a nacrtane su na dijagramu s x i y osima koje se protežu u intervalu (-2, 2). (hint: ax.set_xlim() i ax.set_ylim()).

Zadatak 7

Odredite (x,y) koordinate vrha lijevog “krila” gornjeg “leptira”, dakle točke, negdje oko (x=3, y=3) koja je najudaljenija od ishodišta.

Zadatak 8

Nacrtajte kružnicu u kompleksnoj ravnini zadanu kompleksnim brojevima

\[\{ z = \rho e^{i \eta} (1+e^{i\phi}) - 1 \quad | \quad \phi \in [0, 2\pi), \rho = 1.3, \eta = 0.2 \}\]

te krivulju koja se dobije kad se ova kružnica podvrgne transformaciji Žukovskog:

\[z \to w = \frac{1}{2}\left(z+\frac{1}{z}\right)\]

Footnotes

[1]Postoji i modul pylab sa sučeljem sasvim sličnim komercijalnom programu Matlab. Vidi usporedbu raznih Matplotlib sučelja.
[2]Primjere crtanja iz originalne matplotlib dokumentacije moguće je izravno kopirati u Sage, do na tu zamjenu show() sa savefig('fig'). Usput rečeno, savefig() sprema datoteku sa slikom u \$HOME/.sage/sage_notebook.sagenb/home/<username>/<kk>/cells/<nn>/imeslike.png, gdje je <kk> broj radnog lista vidljiv u URL-u (“WWW” adresi vidljivoj u WWW pregledniku), a <nn> je broj ćelije koji je vidljiv samo u tekstualnoj varijanti radnog lista (tipke "Text" ili "Edit" u notebooku), ali može se saznati i pomoću Unix shell komande find . -name "ime.png" iz direktorija ...<kk>/cells.

Pregled sadržaja

Prijašnja tema

3.3. Funkcije

Slijedeća tema

4. Matematika