Grafica în MATLAB

Grafica face MATLAB un software puternic. Funcţiile de bază sunt simple, dar controlul complet asupra graficelor aduce şi un oarecare grad de complexitate.
Obiectele grafice se clasifică după tipul lor, cele mai importante aparând în figura 1. Ele sunt aşezate într-o ierarhie strictă: fiecare obiect grafic relevant, cum ar fi o linie sau o suprafaţă, trebuie să fie situat într-un sistem de axe, care trebuie să fie situat într-o fereastră a unei figuri, care este descendentă a unei rădăcini virtuale. Dintre numele de comenzi din figura 1, cel mai util este figure, care deschide o noua fereastră de figură. Altele, cum ar fi line sau surface sunt considerate funcţii de nivel inferior şi de obicei nu sunt apelate direct. În loc de aceasta se utilizează funcţii mai prietenoase care crează aceste tipuri de obiecte în interiorul axelor celor mai recent create sau activate printr-un click. La fel, un grup sau o serie de obiecte grafice este de regulă o colecţie de mai multe obiecte primitive care sunt create şi grupate printr-o rutină convenabilă.
Fiecare obiect grafic redat are proprietăţi care se pot seta la creare sau ulterior, pentru a controla aspectul lui. Se pot adăuga axelor etichete, titluri şi alte adnotări. Cele mai multe modificări grafice se pot realiza fie prin comenzi, fie printr-o interfaţă grafică utilizator (GUI). În particular, butonul Edit Plot, care are icon-ul
vă permite să daţi dublu-click sau clic dreapta pe orice obiect grafic pentru a-i schimba atributele. Există o paletă largă de alegeri posibile.
Cuprinsul
close all

Afişarea datelor comparativ cu afişarea funcţiilor

În ultimă instanţă, orice grafic provine din afişarea unor valori numerice. Totuşi, sursa acelor valori ne dictează modul de generare sau utilizare. În multe aplicaţii, sursa este constituită din date observate sau valori discrete ale unei funcţii necunoscute, cum ar fi soluţia unei ecuaţii diferenţiale. În acest caz, conceptual, doriţi să afişaţi o mulţime fixată de puncte în plan sau în spaţiu, posibil cu informaţii vizuale adiţionale cum ar fi culoarea sau liniile de legătura. Functiile ,,tradiţionale'' din MATLAB urmează acest model.
Uneori, totuşi sursa datelor este formată din una sau mai multe funcţii matematice cunoscute. În astfel de situaţii am dori să lucram cu funcţiile şi să avem posibilitatea de a le evalua după nevoi, pentru a genera puncte care fac graficul aspectuos. Pentru a face grafice în acest mod, MATLAB are mai multe funcţii al caror nume începe cu f. Aceste funcţii lucreaza ca functiile grafice din software simbolice ca MuPAD. Totuşi, retineţi că, odată ce punctele sunt generate şi redate, sursa lor este uitată si devine irelevantă -- deci, daca de exemplu se face un zoom pe o parte a unui grafic, graficul nu va fi rafinat, cum se întamplă în multe pachete simbolice.

fplot

Comanda fplot realizează grafice bidimensionale (2D) de funcții explicite, implicite şi parametrice. Acestea sunt reprezentate matematic prin , , sau respectiv prin perechi . Trebuie să furnizăm lui fplot una sau mai multe funcţii care să definească graficul şi să definim domeniul variabilelor, ca în exemplele următoare:
fplot( @sin, [0 2*pi] )
exemplul 2
fimplicit( @(x,y) x.^4+y.^4-1, [-1 1] ), axis equal
exemplul 3
x= @(t) exp(-t).*cos(8*t);
y= @(t) exp(-t).*sin(8*t);
fplot(x,y,[0 3])
De notat că toate funcţiile anonime trebuie să utilizeze operaţii pe tablouri, cum ar fi si .* . Comanda axis equal utilizată în al doilea exemplu face ca axele de coordonate să aibă raportul dintre unităţi (aspect ratio) 1:1, astfel că cercurile nu vor arăta ca elipsele.
Comanda polarplot realizează grafice în coordonate polare, dacă i se dă r ca funcţie de θ .
Comanda fplot3 afişează curbe parametrice în spaţiu:
fplot3(@cos, @sin, @(t) exp(-t/8), [0 40])
Un mod de a vizualiza funcţii de două variabile este de a utiliza grafice de tip contur, în care se reprezintă familiii de curbe în planul pentru mai multe alegeri ale lui c. Există comanda fcontour pentru aceasta:
close all
fcontour(@(x,y) 4*x.^2-x.*y+y.^2, [-1 1 -2 2] )
fcontour(@(x,y) sin(3*x-y).*sin(x+2*y), [-pi pi], 'Fill','on')
A doua formă umple regiunile dintre contururi cu diferite culori.
Pentru o suprafaţă explicită , sau o suprafaţă parametrică în care x, y şi z sunt funcţii de doi parametrii se utilizează fsurf. Funcţia ezmesh produce un grafic de tip cadru de sârmă.
fsurf( @(x,y) x.^2-y.^2-1, [-1 1 -1 1] )
x=@(u,v) cosh(u).*cos(v); y=@(u,v) sinh(u).*cos(v);
z=@(u,v) sin(v); fmesh( x,y,z, [-1 1 0 2*pi] )
În ambele tipuri de grafice, culoarea este utilizată pentru a da informaţii adiţionale despre valorile lui z.
Pentru detalii suplimentare recomandăm consultarea help-ului.

Grafice bidimensionale

Pentru date discrete în două dimensiuni se utilizează plot. De exemplu, MATLAB are datele recensământelor din SUA din perioada 1790–1990:
load census
plot(cdate,pop)
Comanda plot conectează punctele definite prin valorile celor doi vectori de valori ale coordonatelor. Se poate schimba stilul de linie la creare sau după aceea, ca în
plot(cdate,pop,'ro') % red circles
plot(cdate,pop,'k:') % black dotted lines
plot(cdate,pop,'ys-') % yellow squares and lines
Implicit orice grafic nou îl înlocuieste pe cel vechi. Pentru a adăuga noi curbe la graficele curente se poate utiliza hold on. Acest set de date arată mai bine dacă valorile ordonatelor sunt logaritmate:
semilogy(cdate,pop,'p-')
Se poate vedea că datele prezintă o creştere exponenţială, cel puţin până în 1860. Putem adăuga o extrapolare exponenţiala grosieră a datelor de după 1900 după cum urmează:
t = 1900:10:2030;
hold on
semilogy( t, exp(-20.44+0.01306*t), 'k--' )
hold off
De notat că limitele care incadrează datele sunt alese automat. Dacă dorim să minimizăm spaţiul gol, utilizăm axis tight .
Pentru mai multe informaţii, vezi help graph2d sau doc graph2d. Testaţi de asemenea butoanele din fereastra figurilor, care sunt autoexplicative. Încercaţi să daţi click dreapta pe obiecte pentru a le modifica aspectul.

Grafice tridimensionale

Pentru a obţine grafice de suprafeţe şi altele înrudite pentru funcţii de forma se generează întâi o grilă de puncte în planul pe care f este evaluată pentru a obţine puncte în spaţiul tridimensional. Aceasta se realizează cel mai uşor utilizând funcţia meshgrid .
Iată un exemplu tipic:
x = pi*(0:0.02:1);
y = 2*x;
[X,Y] = meshgrid(x,y);
Aceste tablouri definesc punctele unei grile 2D, care se poate vizualiza utilizând
plot(X,Y,'k.')
Cu această definiţie de grilă putem calcula valori pentru coordonata z utilizând operaţii de tip tablou:
Z = sin(X.^2+Y);
surf(X,Y,Z)
Z este efectiv un tablou de valori ale funcţiei evaluate pe grilă. În cele din urmă surf generează un grafic de suprafaţă cu aspect solid (format din petece de suprafaţă - patches), iar cotele sunt date de valorile lui f. Comanda mesh este asemănătoare cu surf, dar generează un grafic de tip cadru de sârmă:
Datorită convenţiilor matematice, ieşirea lui meshgrid este o sursă de confuzie. Problema este că pentru grafice de funcţii, prima variabilă este interpretată ca orizontală şi a doua ca verticală. Într-un tablou A, primul indice de dimensiune este vertical (linie), iar al doilea orizontal (coloană). O complicaţie suplimentară, ignorată de rutina de afişare, este că direcţia verticală, însemnând ,,creştere'' este inversată în cele două interpretări.
Pentru grafice care care reprezintă o matrice pentru inversarea axelor se utilizează axis ij . Funcţia meshgrid şi functiile grafice 3D urmeaza convenţia grafică. Deci, utilizând definiţiile de mai sus, grila de puncte (x(i),y(j)) se va găsi în tablourile de mai sus sub forma (X(j,i),Y(j,i)) . Se poate evita aceasta utilizând ndgrid , care adoptă convenţia tablou în loc de meshgrid , dar apoi toate apelurile de surf şi funcţii înrudite trebuie să transpună toate tablourile, sau altfel graficul va avea axele x şi y transpuse.
Este util de înţeles că, datele se dau pe o grilă logic rectangulară, dar nu efectiv rectangulară. De exemplu, se pot reprezenta grafice de funcţii definite pe discul unitate după cum urmează:
[R,T] = meshgrid( 0:.02:1, pi*(-1:.05:1) );
X = R.*cos(T); Y = R.*sin(T);
pcolor(X,Y,X.^2-Y.^3), axis equal
Orice suprafaţă parametrică definită pe un dreptunghi poate fi reprezentată grafic în acest mod.

Adnotare

Graficele necesită etichete şi titluri. De exemplu:
fplot(@(t) exp(-t/5).*sin(t), [0 6*pi])
xlabel('time')
ylabel('amplitude')
title('Damped oscillator')
Acestea se mai pot adăuga şi edita actionând butonul Edit Plot şi dând dublu click pe axe. Se pot adăuga legende, texte, săgeţi sau combinaţii de texte şi săgeţi pentru a ajuta etichetarea. Vezi meniul Insert din fereastra figurii. MATLAB suportă un set restrâns TeX în şirurile de caractere, inclusiv în etichetele de axe şi în titluri. Se pot astfel genera uşor indici, exponenţi, litere greceşti, simboluri.
xlabel('time \tau')
legend('{\it e}^{-\tau/5} sin(\tau)')
Se pot genera adnotări matematice mai elaborate utilizând interpretorul LaTeX. Deşi s-au adus îmbunatăţiri în ultimele versiuni, rezultatele nu sunt pe măsura documentelor LaTeX. Pentru rezultate mai bune se poate utiliza pachetul psfrag, care permite înlocuirea şirurilor dintr-o figură EPS cu casete (boxes) arbitrare de text procesat în documentele LaTeX.

Handles şi proprietăţi

Orice obiect redat are un identificator (handle). Funcţiile gcf, gca, şi gco returnează handle-uri pe figura, axa sau obiectul activ (de obicei cel mai recent desenat sau pe care s-a dat click). Handle-ul era un număr pana la versiunile 2014; acum este un obiect mai complex. Proprietăţile pot fi accesate şi schimbate la nivel de comandă prin funcţiile get şi set, sau grafic (vezi Plot Edit Toolbar, Plot Browser, şi Property Editor în meniul View al figurii). Iată un exemplu care dă doar o idee despre ce se poate face:
h = plot(t,sin(t))
h =
Line with properties: Color: [0 0.4470 0.7410] LineStyle: '-' LineWidth: 0.5000 Marker: 'none' MarkerSize: 6 MarkerFaceColor: 'none' XData: [1900 1910 1920 1930 1940 1950 1960 1970 1980 1990 2000 2010 2020 2030] YData: [0.6159 -0.0882 -0.4679 0.8734 -0.9978 0.8010 -0.3465 -0.2196 0.7150 -0.9803 0.9300 -0.5805 0.0441 0.5065] ZData: [1×0 double] Show all properties
set(h,'color','m','linewidth',2,'marker','s')
set(gca,'pos',[0 0 1 1],'visible','off')
În versiunile noi atributele grafice pot fi accesate direct.
h = plot(t,sin(t))
h =
Line with properties: Color: [0 0.4470 0.7410] LineStyle: '-' LineWidth: 0.5000 Marker: 'none' MarkerSize: 6 MarkerFaceColor: 'none' XData: [1900 1910 1920 1930 1940 1950 1960 1970 1980 1990 2000 2010 2020 2030] YData: [0.6159 -0.0882 -0.4679 0.8734 -0.9978 0.8010 -0.3465 -0.2196 0.7150 -0.9803 0.9300 -0.5805 0.0441 0.5065] ZData: [1×0 double] Show all properties
h.Color='m'; h.LineWidth=2; h.Marker='s';
ax=gca; ax.Position=[0 0 1 1]; ax.Visible='off';
Handle-urile permit schimbarea uşoară a unui întreg lot de obiecte la un moment dat. De exemplu, secvenţa de mai jos schimbă toate liniile albastre din figura curentă şi le face lăţimea egală cu 3:
h = findobj(gcf,'type','line','color','m')
h =
Line with properties: Color: [1 0 1] LineStyle: '-' LineWidth: 2 Marker: 'square' MarkerSize: 6 MarkerFaceColor: 'none' XData: [1900 1910 1920 1930 1940 1950 1960 1970 1980 1990 2000 2010 2020 2030] YData: [0.6159 -0.0882 -0.4679 0.8734 -0.9978 0.8010 -0.3465 -0.2196 0.7150 -0.9803 0.9300 -0.5805 0.0441 0.5065] ZData: [1×0 double] Show all properties
h.LineWidth=3;
Datorită handle-urilor, graficele în MATLAB pot fi create într-o formă de bază şi apoi modificate după dorinţă. Uneori este util să schimbăm valorile implicite ale proprietăţilor utilizate la redarea iniţială a unui obiect. Aceasta se poate face resetând valorile implicite la orice nivel din ierarhia de obiecte grafice din Figura 5.1. De exemplu, pentru a ne asigura că toate obiectele de tip text vor avea dimensiunea fontului de 10, se introduce
set(gcf,'defaulttextfontsize',10)
Toate figurile sunt considerate copilul obiectului virtual root, proprietăţile acestui obiect creând valori globale implicite.

Culoarea

Colorarea liniilor şi a textelor este uşor de înteles. Fiecare obiect are o proprietate Color, căreia i se poate asocia un vector RGB (red, green, blue) cu componentele luând valori între 0 şi 1.
Culorile primare şi secundare apar în tabela 5.3, împreună cu abrevierile lor de o literă.
Culoarea verde nu se vede bine pe fond alb; MATLAB utilizează un verde închis, [0 0.5 0].
Suprafeţele se colorează diferit. Sunt două aspecte diferite, ambele modificabile: colorarea punctelor ce reprezintă date şi colorarea petecelor de suprafaţă şi liniilor cadru dintre ele. Culorile punctelor se specifică prin proprietatea CData a obiectului suprafaţă. Aceasta se poate specifica prin valorile RGB din fiecare punct, modalitate numită truecolor model . Este cea mai buna pentru fotografii si imagini bitmap.
Modalitatea comună implicită când nu se specifică nici o informaţie de culoare este modelul indexat de culori. Acesta presupune o interacţiune între proprietatea CData a suprafeţei, proprietatea CLim a axelor părinte şi proprietatea Colormap a figurii părinte a axelor. Proprietatea Colormap a figurii este un tablou , în care fiecare linie este interpretată ca un triplet RGB. Proprietatea CLim este un vector [a b] care defineşte o transformare afină de la intervalul la intervalul . Astfel, fiecare valoare din proprietatea CData este modificată conform transformării afine, apoi rotunjită la cel mai apropiat intreg din , care serveşte ca index de linie în harta de culori pentru a determina culoarea. La fel ca toate proprietăţile obiectelor grafice, cele amintite mai sus pot fi modificate cu comanda set. Totuşi există şi alte alternative. Implicit, proprietatea CData a suprafeţei este egală cu tabloul de valori ale coordonatelor z (ZData) ale suprafeţei, dar poate fi setată apelând funcţiile surf şi mesh cu un al patrulea argument. Proprietatea CLim este setată implicit pentru a include toate valorile datelor, şi se poate modifica ulterior utilizând caxis. Harta de culori Colormap implicită începând cu MATLAB 2014b este numita parula. Orice schimbare a acestor proprietăţi, indiferent cum este facută, are efect imediat asupra culorilor:
[X,Y,Z] = peaks; % some built-in data
surf(X,Y,Z)
colorbar % show data->color mapping
caxis
ans = 1×2
-6.5466 8.0752
caxis([-8 8]), colorbar % zero-level symmetry
colormap pink % change figure colormap
colormap gray % change figure colormap
colormap(flipud(gray)) % reverse ordering
Se poate specifica explicit CData pentru o suprafaţă în modelul indexat. O utilizare naturală este prin intermediul unei funcţii de variabilă complexă:
[T,R] = meshgrid(2*pi*(0:0.02:1),0:0.05:1);
[X,Y] = pol2cart(T,R);
Z = X + 1i*Y;
W = Z.^2;
surf(X,Y,abs(W),angle(W)/pi) % arg(W) for coloring
axis equal; colorbar
colormap hsv % periodic colormap
Între punctele grilei, culoarea se determină prin umbrire (shading). Aceasta se poate modifica apelând comanda shading după crearea suprafeţei.
Deşi umbrirea prin interpolare shading interp face culorile mai netede şi graficele mai frumoase, este lentă, în particular la imprimare. De fapt, de multe ori este mai rapid să interpolaţi dumneavoastră pe o grilă mai fină şi să imprimaţi cu shading flat. A se vedea funcţia interp2 .

Salvarea şi exportul figurilor

Uneori o figură are nevoie de modificări la mult timp după crearea sa. Se pot salva comenzile de creare a figurii într-un script, dar dacă figura ia mult timp pentru generare, rularea repetată va fi consumatoare de timp. De asemenea, editările făcute prin meniuri şi butoane se vor pierde.
În loc de aceasta se poate salva figura într-un format care permite recrearea sa în sesiunile următoare, prin comanda
saveas(gcf,'myfigure.fig')
Figura curentă se salvează în fişierul myfigure.fig . (Acest lucru se poate şi prin Save as… din meniul File al figurii.) Mai târziu se poate deschide myfigure.fig pentru a genera din nou figura pe ecran. Doarece obiectele grafice memorează datele care le definesc (în proprietăţile XData , YData si ZData ), aceasta este şi o modalitate de a memora datele utilizate pentru a crea graficul. Se pot memora informaţii utilizator de spre obiect în câmpul UserData .
Dacă doriţi să introduceţi figurile în documente sau prezentări, trebuie să exportaţi fişierele grafice. (Operaţiile copy sau paste pot fi utile în unele situaţii particulare, dar în altele rezultatul este nesatisfăcător.)
În acest proces, ceea ce se vede pe ecran nu coincide cu ceea ce este în fişierul grafic, deoarece MATLAB tratează graficele diferit, în funcţie de dispozitivul de ieşire. Pentru setarea caracteristicilor se poate folosi Export setup. . . din meniul File al figurii. El vă permite să salvaţi o colecţie de preferinţe sub forma unui nume de stil. Totuşi, acest mod poate afecta proprietăţile setate prin handle-uri şi în acest caz este de preferat lucrul cu comenzi. Iată câteva aspecte care trebuie luate în considerare la exportul unei figuri:
Mărimea. La prima vedere pare irelevantă, deoarece programele de editare de texte vor schimba mărimea imaginilor în documentul final. Totuşi, redimensionarea după export poate scala totul, inclusiv textele ducând la linii foarte subţiri sau texte scrise cu fonturi foarte mici. Este mai bine să lăsaţi MATLAB să seteze mărimea figurilor, lăţimea liniilor şi înainte de export.
Format. Cea mai importantă diferenţă între formatele grafice este dintre formatele vectoriale (cum ar fi EPS, PDF, şi EMF) şi formatele bitmap (cum ar fi GIF, JPEG, PNG şi TIFF). Bitmap, care memorează pixeli sunt ideale pentru fotografii, dar mai puţin adecvate pentru aplicaţii ştiinţifice. Aceste formate fixează rezoluţia imaginilor, în timp ce rezoluţia diverselor dispozitive poate fi variabilă. Formatele vectoriale, care reprezintă liniile, textele şi suprafeţele mai abstract, prin coordonate, sunt alegeri mult mai bune pentru grafice dependente de date.EPS (encapsulated PostScript) este formatul cel mai potrivit pentru a fi inclus în documente LATEX. El conţine informaţii despre caseta ce mărgineşte graficul (bounding box) care permit LATEX să calculeze exact dimensiunea graficului. Pentru exportul din linia de comandă se poate utiliza
print -deps myfig
sau, pentru grafice colorate,
print -depsc myfig
pentru a crea fişierul myfig.eps din figura curentă. Totuşi, această metodă utilizează proprietatea PaperPosition a figurii, nu poziţia pe ecran, pentru a determina mărimea graficului la ieşire. Formatul EPS se poate folosi şi din Microsoft Word™, dacă se listează pe o imprimantă PostScript printer. În acest caz este convenabil să se utilizeze
print -deps -tiff myfig
în care caz Word va putea face şi preview pe ecran.
Dacă formatul de ieşire este PDF, EPS nu poate fi utilizat direct. Se pot genera figuri în format PDF sau PNG.
Culoarea. Liniile colorate sunt convertite automat în negru, dacă salvarea se face în alb-negru. În acest caz trebuie facută distincţie între linii prin stil sau simboluri. Suprafeţele colorate sunt convertite în niveluri de gri, ceea ce poate prezenta probleme. Harta implicită de culori merge de la albastru intens la roşu intens, iar tonalitatea dă informaţii reale despre suprafaţă. La conversia în niveluri de gri distincţia dintre rosu şi albastru nu este clară, iar umbrele devin fără sens. Pentru un grafic de suprafaţă cu niveluri de gri se poate utiliza colormap(gray) sau colormap(flipud(gray)), care lasă mai puţin negru înainte de export, astfel că saturaţia corespunde datelor. Muchiile graficelor wireframe create cu mesh sunt convertite în gri, frecvent cu rezultate modeste. Faceţi toate liniile negre cu colormap([0 0 0]).

Alte tehnici grafice

Pentru a crea un tablou de grafice într-o fereastră de figură, utilizaţi subplot. De exemplu:
t=linspace(0,2*pi,200);
for n = 1:6
subplot(2,3,n)
polarplot(t,sin(n*t))
title(['r = sin(',int2str(n),'t)'])
end
delete(findobj(gcf,'type','text')) % generic labels
Apelul subplot(m,n,k) selectează a k-a axă dintr-un tablou , numarând de la stânga la dreapta şi de sus în jos.
Iată şi o modalitate de a realiza grafice dinamice sau animaţie:
figure('doublebuffer','on') % flash-free redraws
t = linspace(0,8*pi,800)';
for s = 0:0.01:1
x = exp(-s*t).*cos(6*s*t+t);
y = exp(-s*t).*sin(6*s*t+t);
plot(x,y), axis ([-1 1 -1 1])
pause(0.01)
end
Comenzile grafice se acumulează într-un buffer şi nu au efect imediat. Acest fapt ne permite să facem schimbări multiple între cadrele animaţiei. Trebuie utilizat pause sau drawnow ori de câte ori dorim să forţăm execuţia comenzilor grafice din buffer.
Tehnica de animaţie este cu atat mai bună cu cât timpul necesar pentru redarea fiecărui cadru este mai mic. O alternativă este să facem un film de bitmap-uri de cadre (frames), utilizând getframe pentru a memora fiecare cadru. Filmul poate fi proiectat cu movie sau convertit într-un fişier video cu movie2avi .
În general, când o funcţie grafică întâlneşte o valoare NaN într-o listă de puncte, ea omite să le deseneze. Acest lucru este util în combinaţie cu tehnici de mascare (prin indici logici). Comenzile de mai jos desenează o suprafaţă definită pe o regiune în formă de L:
[X,Y] = meshgrid( -1:1/18:1 );
L = membrane(1,18,8,8);
surf(X,Y,L)
Pentru acest grafic, valorile z dinafara domeniului sunt setate la zero, ceea ce nu este rău deoarece valoarea pe frontieră este zero. Dar graficul se îmbunatăţeşte, dacă ştergem partea respectivă din suprafaţă utilizând NaN:
outside = (X < 0) & (Y > 0); % logical index mask
L(outside) = NaN; % note "scalar expansion"
surf(X,Y,L)

Bibliografie

Higham, N. H. (2009). MATLAB Guide. Philadelphia: SIAM.
Moler, C. (2004). Numerical Computing in MATLAB.Philadelphia: SIAM
Driscoll, T. (2009). Learning MATLAB. Philadelphia: SIAM