S
TEROWANIE
R
OBOTAMI
C
WICZENIA
L
ABORATORYJNE NR
2
G
RAFIKA W
M
ATLABIE
Akademia Górniczo – Hutnicza w Krakowie
Grafika w Matlabie
Tworzenie rysunków dwuwymiarowych
Zwykle dwuwymiarowe rysunki moga byc generowane w Matlabie przy uzyciu polecenia plot. Najprostsze
uzycie tej komendy polega na podaniu wektora liczb, jako jedyny parametr wejsciowy. Dokladniej mówiac,
jezeli wprowadzisz komende plot(v), gdzie v bedzie dowolnym wektorem liczb rzeczywistych, Matlab stworzy
wykres wielkosci v od jej indeksów. To znaczy, pierwszy element wektora v bedzie posiadal rzedna 1, drugi – 2,
itd.
>> v = logspace (0, -5, 12);
>> plot (v)
Rezultatem tej sekwencji komend jest wykres ukazany na rys. 1
0
2
4
6
8
1 0
1 2
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Rys. 1. Wykres wektora zawierajacego 12 elementów, logarytmicznie rozmieszczone od 10
0
do 10
-5
Zauwaz, ze skalowanie osi przebiega w sposób automatyczny tak aby wykres zawieralwszystkie wartosci v .
Polecenie plot(v) zwróci inny wykres, gdy v bedzie zawieral wartosci zespolone. W przypadku tym otrzymamy
wykres vartosci czesci rzeczywistych od urojonych vektora.
Jezeli argumentem wejsciowym plot bedzie macierz, Matlab potraktuje kazdy wiersz macierzy jako osobny
wektor i narysuje tyle przebiegów na jednym wykresie, ile wierszy ma macierz. Skrypt hilbplot.m zamieszczony
ponizej tworzy maciez hilberta o wymiarach 5 x 5 H, i rysuje ja. Pierwsza komenda w hilbplot.m, clf, czysci
okno graficzne. Warto umieszczac te komende na poczatku wszystkich funkcji i skryptów poslugujacych sie
grafika, aby uniknac niezamierzonego nakladania sie rysunków.
hilbplot.m
% hilbplot
% Creates a 5x5 Hubert matrix and plots its rows.
clf
% Clear graphics window
H = hilb (5);
% Create a 5 by 5 Hilbert matrix
plot(H)
% Plot the matrix
Rezultat jej wykonania jest pokazany na rys. 2. Jak widac rysunek jest bardzo nieczytelny, gdyz poszczególne
wykresy sa nieopisane. Wkrótce dowiesz sie jak opisywac poszczególne linie na wykresie, teraz jednak wiemy,
ze wartosci w kolejnych kolumnach w macierzy Hilberta maleja monotonicznie. Mozemy na tej podstawie
wydedukowac, iz wykres „najwyzszy” przedstawia wiersz pierwszy, nizszy – drugi itd.
1
1.5
2
2.5
3
3.5
4
4.5
5
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Rys. 2. Wykresy kolejnych wierszy 5 x 5 macierzy Hilberta
Jezeli napiszesz w przestrzeni roboczej Matlaba plot(x,y), gdzie x i y sa wektorami o równej dlugosci
(wysokosci), powstanie wykres wartosci y od x. Na przyklad, rysunek 3 pokazuje efekt wykonania skryptu
gaussplot.m, którego listing znajduje sie ponizej.
-5
-4
-3
-2
-1
0
1
2
3
4
5
0
0.05
0.1
0.15
0.2
0.25
0.3
0.35
0.4
Rys. 3. Wykres krzywej Gaussa z jednym punktem blednym
gaussplot.m
% gaussplot
% Creates a plot of the Gaussian density function with
% one randomly chosen erroneous point.
clf
x = [ -5 : 0.1 : 5];
% generate a vector of x-values
y = exp( -(x.^2)/2) / sqrt(2*pi);
% compute corresponding y-values
z=10*(rand (1) - 0.5);
% generate a random number
k=1;
% set the index to 1
while z >= x (k)
% compare the random number to the x-values
k=k+1;
% increment the index while z >= x(k)
end
% needed termination of while loop
y (k+1) = 0.1 + y(k+1);
% add error to y(k+1)
plot(x,y)
% plot result
Pierwsza linia tworzy wektor wartosci osi poziomej x. Druga odpowiadajace im wartosci y. Zwróc uwage na
zastosowanie polecenia .^2. Podnosi ona do kwadratu kazdy element wektora x. W razie uzycia skladni ^2
otrzymalibysmy komunikat bledu, informujacy nas o próbie mnozenia dwóch macierzy o niedopasowanych
wymiarach. Bardzo przydatny do wykonywania wykresów jest zbiór komend sluzacych do operacji na tablicach
liczb (.^, .*, ./, itd.). Wykasowanie nastepnych szesciu linii (sa pisane z wcieciem) i pozostawienie tylko
ostatniej, pozwoli na uzyskanie klasycznej krzywej dzwonowej. Zauwaz, ze pierwszy argument komendy plot
jest interpretowany jako zbiór wartosci na osi poziomej, a drugi – pionowej.
Szesc dodatkowych linii w gaussplot.m, powoduje umyslne wprowadzenie falszywego punktu na wykresie.
Trzecia linia w pliku generuje losowa liczbe z zawarta w przedziale od –5 do 5. Polecenie rand(I) znajduje
losowa wartosc z przedzialu od 0 do 1, z jednorodnym rozkladem prawdopodobienstwem. Reszta linii trzeciej
normalizuje wylosowana wartosc do przedzialu (-5,5).
Nastepne cztery linie skryptu porównuja losowa wartosc z z elementami wektora x. Chcemy znalezc pare liczb
wektora x, która otacza liczbe z. Wygodnie jest w tym celu wykorzystac petle while. Gdy z < x (k) po raz
pierwszy, program wyjdzie z petli. Wartosc k stanowi indeks najwiekszego elementu wektora x, który jest wciaz
mniejszy od z. Dodajemy wtedy wartosc 0.1 do k +1-ego elementu wektora y. Po pierwszym wykonaniu
programu znieksztalcenie jest prawie niezauwazalne. Wielokrotne wykonywanie programu spowoduje
generowanie innego wykresy za kazdym razem.
Aby narysowac kilka zaleznosci x od y na jednym wykresie, istnieje kilka mozliwosci. Na przyklad,
plot(x1,y1,x2,y2,x3,y3) narysuje wykres z trzema liniami (y1 od x1, y2 od x2, y3 od x3). Inny sposób to uzycie
polecenia plot(X,Y), gdzie X i Y to macierze. W tym przypadku Matlab narysuje zaleznosci pomiedzy
odpowiednimi kolumnami obu macierzy. Wprowadz help plot, aby poznac wiecej szczególów.
Gdy wykres zostanie juz stworzony, mozna z niego odczytywac wartosci przy pomocy polecenia ginput. Na
przyklad mozesz wykorzystac ginput, aby znalezc wspólrzedne punktu falszywego na rysunku 3. Wpisanie
[xerror,yerror] = ginput spowoduje pojawienie sie krzyza na wykresie. Mozna nim poruszac za pomoca myszy
lub kursorów. Gdy najedziesz na interesujacy cie punkt, kliknij na nim lub nacisnij dowolny klawisz oprócz
klawisza Enter. Matlab obliczy wspólrzedne, na których znajduje sie krzyz. Mozesz odczytac polozenie wielu
punktów przez powtarzanie tej procedury. Gdy skonczysz, nacisnij Enter. Matlab wyswietli zawartosc
zmiennych xerror i yerror, czyli wspólrzedne wszystkich wybranych przez ciebie punktów:
>> [xerror, yerror] = ginput
xerror =
–2.4856
yerror =
0.1168
Oprócz polecenia plot Matlab posiada jeszcze inne komendy pozwalajace na tworzenie rysunków
dwuwymiarowych. Ich dzialanie jest identyczne jak plot, ale inaczej skaluja wykresy. Loglog, semilogx,
semilogy generuja wykresy z jedna badz dwiema skalami logarytmicznymi. Komenda polar tworzy wykres
biegunowy, a bar i stairs zwracaja wykresy kolumnowy i schodkowy. Polecenia bar i sairs maja tylko jeden
argument wejsciowy. Spróbuj podmienic komende plot w powyzszych przykladach, np. na loglog i obejzyj
efekty. Wykorzystaj tez wiadomosci zawarte w pomocy.
Matlab udostepnia tez funkcje print, która umozliwia wykonywanie wydruków wysokiej rozdzielczosci twoich
rysunków. Wpisanie samego polecenia print powoduje wyslanie grafiki bezposrednio na drukarke. Gdy po
komendzie wpiszemy nazwe pliku Matlab wydrukuje rysunek do pliku postskryptowego o nazwie podanej przez
ciebie. W celu poznania szczególów poslugiwania sie poleceniem print, wpisz help print lub help printopt.
Polecenie print moze byc niedostepne na niektórych komputerach z mala iloscia pamieci.
Obróbka rysunków
Metody obróbki grafiki sa przydatne nie tylko w celu dodania informacji takich, jak tytuly i etykiety na
wykresach, lecz równiez po to aby lepiej przedstawic dane oraz szczególy niewidoczne na standardowych,
automatycznie skalowanych wykresach. Dodawanie tytulu, etykiet osi i przebiegów jest czynnoscia bardzo
prosta, jednakze przeskalowywanie wykresów dla ich wiekszej czytelnosci moze wymagac rozsadku i twórczego
myslenia.
Title, xlebel i ylebel tytuluja i dodaja etykiety osi, twojego wykresu. Podobnie komenda grid nanosi linie siatki.
Dla przykladu, dodaj cztery nastepujace linie do skryptu gaussplot.m:
title('Plot of Gaussian Probability Density Function')
xlabel('x values')
ylabel('y values')
grid
Wykonaj gaussplot.m jeszcze raz aby zobaczyc w jaki sposób zostana wyswietlone tytul, etykiety i siatka.
Nadawanie nazw punktom charakterystycznym na wykresie, moze byc wykonane przy pomocy polecen text i
gtext. Komenda text sluzy do recznego etykietowania, tzn: musisz okreslic wspólrzedne pierwszej litery
etykiety. Komenda gtext jest narzedziem do interaktywnego etykietowania. Po wygenerowaniu rysunku napisz
gtext(‘etykieta’). Na rysunku pojawi sie krzyzyk, którym mozesz poruszac za pomoca myszy lub strzalek,
przemieszczajac go do miejsca, w którym powinna pojawic sie etykieta. Nastepnie kliknij lewym klawiszem
myszy albo nacisnij enter i na prawo od miejsca, które wybrales pojawi sie etykieta. Przyklady na zastosowanie
text i gtext znajduja sie w nastepnej sekcji. Spróbuj wykorzystac poznane polecenia do opisu linii na wykresie
wygenerowanym przez hilbplot.m
Spróbuj teraz zamienic w pliku gaussplot.m linie plot(x,y) na plot(x,y,’- -’) i wykonaj go ponownie. W miejsce
domyslnej linii ciaglej, powinna pojawic sie linia przerywana. Matlab zapewnia duzy wybór rodzajów linii,
punktów oraz kolorów tak, iz mozesz dopasowac wykres dokladnie do twoich potrzeb. Aby obejrzec pelna
palete dostepnych kolorów i typów linii napisz help plot.
Uzycie skali logarytmicznej na wykresie jest wygodnym sposobem na przedstawienie danych o róznych skalach
amplitud, bez utraty istotnych informacji. Wykres Bodego wykorzystywany w teorii sterowania jest doskonalym
przykladem. Prostszy przyklad jest przedstawiony na rysunku 4, powstalym jako efekt wykonania pliku
logplot.m. W przykladzie tym uzyta zostala takze komenda subplot, któ®a umozliwia umieszanie wielu
wykresów w jednym oknie graficznym.
logplot.m
% logplot
% Generates a pair of plots that illustrate the
% importance of proper scaling.
clf;
%clear graph window
v1 = logspace (10, 0, 20);
% generate a logarithmic vector
v2 = logspace (2, -2, 20);
% generate a logarithmic vector
v = [v1 v2];
% concatenate the two vectors
subplot (1,2,1), plot (v)
% split screen & plot the
subplot (1,2,2), plot ( log(v) )
% vector plot log of the vector
0
1 0
20
3 0
40
0
1
2
3
4
5
6
7
8
9
10
x 1 0
9
0
1 0
2 0
3 0
40
-5
0
5
1 0
1 5
2 0
2 5
Rys. 4. Wykres wektora zawierajacego dane o wartosci od 10
10
do 10
-2
. Prawy wykres jest w skali dziesietnej
natomiast lewy w skali logarytmicznej (opartej na logarytmie naturalnym)
Wykres po lewej stronie ukazuje przebieg wektora v w funkcji swoich indeksów. Wektor v stanowi polaczenie
wektorów v1 i v2. To znaczy pierwsze 20 elementów wektora v to elementy wektora v1, a nastepne 20 to te z
wektora v2. Na wykresie z prawej strony znajduje sie przebieg wartosci logarytm wektora v. Ja widac wartosci z
wektora v2 sa niewidoczne na wykresie z lewej strony (konwencjonalnym). Wykres logarytmiczny po prawej
dokladnie ukazuje zarówno wartosci v1 jak i v2.
Polecenia subplot(1, 2, 1) i subplot(1, 2, 2) dziela okno graficzne na dwie, równe znajdujace sie obok siebie
polówki. Polecenie subplot(a, b, c) (gdzie a b c to liczby naturalne) tworzy tablice wykresów o wymiarach a na
b. Parametr c wskazuje biezacy wykres to znaczy ten, do którego bedzie wysylany efekt dzialania polecen plot,
semilogx, itp.
Aby powrócic do try bu domyslnego (jeden wykres w oknie graficznym) nalezy uzyc polecenia subplot(1, 1, 1).
Jak sie czesto zdarza, istnieja inne sposoby stworzenia wykresów takich jak na rys. 4. W tym przypadku mozna
zamienic polecenie plot(log(v)) na semilogy(v).
Warto prezentowac dane na kilka róznych sposobów aby miec pewnosc, ze nie przeoczymy istotnej informacji w
nich zawartych. Istnieja sytuacje, gdzie nie mozna zastosowac skali logarytmicznej (tylko liczby dodatnie
posiadaja logarytmy w dziedzinie liczb rzeczywistych). Stosowanie skali logarytmicznej moze tez w niektórych
przypadkach byc nieporzadane lub mylace. Poniewaz logarytm zmniejsza duze wartosci, a male wartosci liczb
dodatnich zmienia w duze ujemne. Wlasciwosci te moga zamienic latwo rozpoznawalny wykres np. 1.01+sin(t)
w cos calkowicie nieidentyfikowalnego.
Ponizszy przyklad ilustruje kolejny przyklad radzenia sobie z danymi trudnymi do skalowania. Maly sygnal (w
tym przypadku sinusoida) nalozony na duzy (fala prostokatna) to czesty przypadek w badaniach inzynierskich.
Niezwykle trudno jest przedstawic dane tak aby nie stracic informacji zawartej w malym sygnale. Inzynierowie
energetycy maja do czynienia z malymi, wynoszacymi 50 Hz (60 Hz w Stanach Zjednoczonych) falowaniami w
liniach energetycznych nalozonymi na inne sygnaly. Plik ripple.m demonstruje technike wyswietlania obu
czesci kombinowanego sygnalu.
ripple.m
% ripple
% Creates plots that illustrate the value of removing
% large known signals from the plot.
clf
v_ripple = [100 * ones(1, 20) zeros(1, 20)] + 0.1 * sin( 1 : 40);
plot(v_ripple)
disp('Pres any key')
pause
subplot(121),
plot(v_ripple( 1 : 20))
subplot(122),
plot( (21 : 40), v_ripple( 21 : 40 ) )
Piata linia pliku tworzy jeden okres fali prostokatnej o amplitudzie 100 i okresie 40 dodany do sinusoidy 0,1
sin(t). Szósta linia generuje wykres pokazany w górnej czesci rysunku 5. Widoczne jest, iz mala sinusoida jest
niedostrzegalna. Problemem jest fakt, ze grubosc linii reprezentujacej fale prostokatna w zadanej skali jest
wieksza niz amplituda malego sygnalu. Dwie ostatnie linie programu tworza polozone obok siebie wykresy
polówek sygnalu. Sa one przedstawione w dolnej czesci rysunku 5. Pierwsza polowa okresu fali prostokatnej,
gdzie sygnal ma stala wartosc 100, znajduje sie z lewej strony, po prawej jest umieszczony wykres drugiej czesci
sygnalu o stalej wartosci 0. Mala sinusoida jest teraz bardzo wyraznie widoczna. Ze wzgledu na fakt iz na obu
sasiadujacych wykresach duzy sygnal ma stala wartosc, Matlab automatycznie skaluje okna do malej sinusoidy
jako jedynego zmiennego przebiegu. Dopiero po dokladnym obejrzeniu obu dolnych wykresów mozna
zauwazyc, ze wartosci na osi y sa rózne.
Zauwaz, ze kod w pliku ripple.m jest nieco bardziej zageszczony w porównaniu do poprzednich przykladów.
Jest on dzieki temu nieco bardziej efektywny, poniewaz zuzywa mniej pamieci i wykonuje sie szybciej.
Jednakze kod jest przez to mniej przejrzysty co czyni jego debugowanie trudniejszym.
0
5
10
15
2 0
25
30
3 5
40
-20
0
20
40
60
80
100
120
0
5
10
15
20
99.9
99.95
100
100.05
100.1
100.15
20
25
3 0
3 5
40
-0.1
-0.05
0
0.05
0.1
Rys. 5 Rezultat wykonania pliku ripple.m
Dwie kolejne komendy Matlaba, hold i axis, sluza do dopasowywania wykresów do wlasnych wymagan. Nalezy
jednak uwazac przy ich uzywaniu, gdyz bledne zastosowanie powoduje problemy. Polecenie hold sluzy do
nakladania jednego wykresu na drugi. Dokladniej hold on zatrzymuje biezacy wykres w oknie graficznym
Matlaba, i wszystkie nastepujace polecenia zwiazane z grafika sa nakladane na siebie, dopóki nie zostanie
wprowadzone polecenie hold off. Samo polecenie hold przelacza tryb z wlaczonego na wylaczony i odwrotnie.
Ze wzgledu na fakt, iz nie zawsze wiadomo, który tryb jest wlaczony, lepiej stosowac hold on i hold off.
Mozesz jednakze sprawdzic jaki jest status wykresu wprowadzajac polecenie ishold. Matlab zwróci 1 gdy tryb
jest wlaczony i 0 gdy tryb jest wylaczony.
Polecenie axis pozwala samodzielnie zdefiniowac zakres osi wykresu. Na przyklad, axis([-5, 5, 0, 10]) ustawi
zakres osi poziomej od -5 do 5, a pionowej od 0 do 10. Wpisanie hold on a potem axis(axis) w nastepnej linii
zamrozi biezacy zakres osi. Aby powrócic do automatycznego skalowania wystarczy wpisac axis(‘auto’).
Tworzenie wykresów trójwymiarowych
Matlab umozliwia przedstawianie danych trójwymiarowych na trzy nastepujace sposoby: wykres poziomicowy,
wykresy typu mesh i wykresy liniowe w przestrzeni trójwymiarowej. Te ostatnie sa wykonywane przy pomocy
komendy plot3, która jest trójwymiarowym odpowiednikiem polecenie plot. Pozostale dwa rodzaje wykresów
zostaly zaprezentowane w skrypcie simple3d.m, a efekt jego dzialania mozna zobaczyc na rysunku 6. Funkcja,
która jest reprezentowana przez ponizsze wykresy to z = x
4
+(y / 2)
4
. Pionowa os wykresów to z i odpowiada z.
Dwie pierwsze linie skryptu tworza wektory x i y. Beda to osie plaszczyzny poziomej. Trzecia linia wprowadza
komende meshgrid. Polecenie to bierze wektory x i y i tworzy z nich tablice X i Y, które zostana wykorzystane
do reprezentacji funkcji dwóch zmiennych takiej jak z. Kazdy wiersz X jest równy wektorowi x, liczba wierszy
X jest równa dlugosci wektora y. Natomiast kazda kolumna Y to wektor y’, i liczba kolumn Y jest odpowiednio
równa dlugosci x. Nastepna linia wylicza wartosci z w macierzy poprzez odpowiednie operacje na tablicach X i
Y. Kazdemu punktowi w prostokatnej siatce stworzonej przez meshgrid odpowiada wartosc z. Ostatnie dwie
linie generuja wykresy poziomicowy i mesh.
simple3d.m
% simple3d
% This creates a contour plot of a simple quartic
% function on the left of the screen and a 3D
% perspective (mesh) plot of the same function on
% the right.
clf
x = [-1 : 0.1 : 1];
y = [-2 : 0.1 : 2];
[X, Y] = meshgrid (x, y);
z = X.^4 + (Y/2).^4;
subplot (1, 2, 1), contour(z)
subplot (1, 2, 2), mesh(z)
Rys. 6. Wykres poziomicowy i typu mesh z = x
4
+(y / 2)
4
Kazda krzywa na wykresie poziomicowym reprezentuje wartosci x i y, którym odpowiada ustalona wartosc z.
Pozioma plaszczyzna x - y jest plaszczyzna papieru (monitora). Przy takim ustawieniu trudno jest ocenic czy
wartosci z maleja czy rosna wraz z zaciesnianiem sie poziomic. Zauwaz, ze krzywe poziomic maja ksztalt
prostokatów z zaokraglonymi rogami. Jest to efekt wystapienia x i y w czwartej potedze, gdyby byly
podniesione do kwadratu, krzywe mialyby ksztalt eliptyczny. Wykres po lewej to aksonometryczna,
odpowiednio pocieniowana reprezentacja tej samej funkcji. To dobry sposób przedstawianie danych na obu
wykresach. Mesh daje lepsze wyobrazenie o ksztalcie i zmiennosci przebiegu danych. Mozna opisywac
poszczególne poziomice na wykresie poziomicowym przy pomocy polecenia clabel.
Zauwaz, ze osie na obu wykresach sa zle opisane. Matlab zaklada, ze wartosci na osiach x i y to indeksy
macierzy z, dopóki nie zdefiniujesz ich inaczej. Mozna to prosto zrobic, zastepujac polecenie mesh(z)
wyrazeniem mesh(x, y, z) oraz analogicznie contour(z) na contour(x, y, z, 10) w pliku simple3d.m. Liczba 10
w skladni polecenia contour oznacza ilosc poziomic jaka ma zostac wykreslona. Aby poznac lepiej mozliwosci
wykorzystania powyzszych komend uzyj help.
Cwiczenia
Cwiczenie 1
Wygeneruj wykres krzywej Gaussa przy pomocy polecen bar, stairs, semilogy i loglog.
Cwiczenie 2
Zamien komende plot(log(v)) w pliku logplot.m na semilogy(v). Wykonaj plik jeszcze raz i porównaj efekt
dzialania z poprzednim.
Cwiczenie 3
Stwórz i wykonaj nastepujacy skrypt: hiddens.m
v = ( 100 * rand(1) ) * sin ( (rand(1) * 10) * [0:0.1:10]) + 0.1 * sin ( [0 : 0.1 : 10] );
plot (v)
apisz skrypt, który zidentyfikuje i usunie sygnal losowy i narysuje wykres malej sinusoidy. Twoje rozwiazanie
moze wykorzystac jedynie wektor v i polecenie plot.
Literatura
[1] Brzózka J.: Cwiczenia z automatyki w Matlabie i Simulinku. MIKOM, Warszawa 1997
[2] Matlab User’s Guide
[3] Simulink User’s Guide
[4] Leonard N., Levine W.: Using Matlab to Analyze and Design Control System. The Benjamin/Cummings
Publishing Company, 1995
[5] Zalewski A., Cegiela R.: Matlab – obliczenia numeryczne i ich zastosowania. NAKOM, Poznan 1996