O kolorowaniu wykresów w MATLABie

„Selektywne wykresy”

Table of Contents

Wstęp

Bardziej skomplikowany przykład: kolorowanie wykresu w załeżności od wartosci zmiennej zależnej

Podejście alternatywne

Jeszcze inaczej

Wstęp

Czasami istnieje potrzeba wybrania z danych (do prezentacji graficznej, na przykład) wartości spełniających określone warunki.

Do wybrania tych wartości nie warto stosować klasycznej pętli for. Są na to lepsze sposoby.

x = 0:0.1:10;
y = sin(x);

Chcemy wybrać wartości x zawarte między 1 a 2 (włącznie) czyli $1\le x\le 2$ :

wybor = (x >= 1) & (x <= 2)
wybor = 1x101 logical array
   0   0   0   0   0   0   0   0   0   0   1   1   1   1   1   1   1   1   1   1   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

Wykonanie powyższego polecenia tworzy tablicę logiczną zawierającą zera (fałsz) tam gdzie warunek nie jest spełniony i 1 (prawda) tam gdzie jest spełniony. Można jej używać do „filtrowania” wartości:

X = x(wybor)
X = 1x11
1.0000    1.1000    1.2000    1.3000    1.4000    1.5000    1.6000    1.7000    1.8000    1.9000    2.0000
Y = y(wybor)
Y = 1x11
    0.8415    0.8912    0.9320    0.9636    0.9854    0.9975    0.9996    0.9917    0.9738    0.9463    0.9093

i rysowania wykresu:

plot(X,Y)

figure_0.png

Bardziej skomplikowany przykład: kolorowanie wykresu w załeżności od wartosci zmiennej zależnej

Załóżmy że chcemy pokolorować na niebiesko wartości większe od zadanego współczynnika $\alpha$ ; na czerwone będą wartości nie spełniające tego warunku

alpha = 0;
wybor = y >= alpha;

Tablicy wybór użyjemy do „odfiltrowania” wartości zmiennej zależnej, ale też zmiennej niezależnej:

plot(x(wybor),y(wybor),'b')

figure_1.png

Do wyboru wartości nie spełniających warunku wybierzemy negację zmiennej wybór ~wybor

plot(x(~wybor), y(~wybor), 'r')

figure_2.png

Polaczmy te wykresy:

X1 = x(wybor);
Y1 = y(wybor);
X2 = x(~wybor);
Y2 = y(~wybor);
plot(X1, Y1, 'b', X2, Y2, 'r')

figure_3.png

Efekt, nie jest do końca zadawalający, choć coś takiego wygląda już lepiej

plot(X1, Y1, '+b', X2, Y2, '+r')

figure_4.png

Podejście alternatywne

Polega ono na wykorzystaniu faktu, że gdy wśród danych pojawią się wartości NaN (Not a number) to są one w sposób specjalny traktowane przez funkcję plot

yy = y;
yy(5:10) = NaN;
plot(x,yy)

figure_5.png

punkty od piątego do dziesiątego z wykesu znikają…

Zatem można zrobić tak:

gora = y;
dol = y;

gora to będą te punkty mktóre mają być zaznaczone jako większe niż:

gora(~wybor) = NaN;

zatem dol będzie zdefiniowane tak:

dol(wybor) = NaN;
plot(x,gora,'b',x, dol, 'r')

figure_6.png

Wygląda już znacznie lepiej, ale wyraźnie widoczne są te przerwy (które znikną, gdy funkcja będzie gęściej próbkowana.

Jeszcze inaczej

„Przerwy” wynikają z tego, że wybory dokonywane warunkami raz: $y>\alpha$ i drugim razem $y<=\alpha$ są rozłączne, gdyby dobrać wartość $\alpha$ tak, żeby istniały takie punkty, że $y=\alpha$ , być może dałoby się zlikwidować te luki. Sprawdźmy

alpha = 0.35;
x = 0:0.1:10;
y = sin(x);
wybor = y == alpha;

Jak można się domyślećwarunek ten będzie spełniony wyłącznie dla $x=0$ …

Co prawda w MATLABie istnieje funkcja isapprox() ale dotyczy ona tylko równości, ale można zdefiniować tolerancję:

tol = 0.05;
wybor = isapprox(y, alpha, AbsoluteTolerance=tol);
plot(wybor,'o')

figure_7.png

Teraz już widac te rozmycie.

To teraz zdefiniujmy punkty, które są „w przybliżeniu” na górze:

wybor1 = (y - alpha) >= tol | wybor;

i te, które „w przybliżeniu” są na dole:

wybor2 = (y - alpha) <= -tol | wybor;
gora = y;
dol = y;
gora(wybor2) = NaN;
dol(wybor1) = NaN;
plot(x,gora,'b',x, dol, 'r',x,y,'+')

figure_8.png

Teraz tylko trzeba punkty pośrednie zaliczyć do obu klas. Punkty „pośrednie” to te, w których zmienne wybor2 i wybor1 mają wartość NaN, zatem:

nany = isnan(gora) & isnan(dol);
gora(nany) = y(nany);
dol(nany) = y(nany);
plot(x,gora,'b',x, dol, 'r',x,y,'+')

figure_9.png

Powyższe rozumowanie ma, oczywiście, pewne dziury…

Wojciech Myszka
Wojciech Myszka
dr inż. adiunkt

Tak się tylko rozglądam…