O kolorowaniu wykresów w MATLABie

„Selektywne wykresy”
Table of Contents
Bardziej skomplikowany przykład: kolorowanie wykresu w załeżności od wartosci zmiennej zależnej
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)

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')

Do wyboru wartości nie spełniających warunku wybierzemy negację zmiennej wybór ~wybor
plot(x(~wybor), y(~wybor), 'r')

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

Efekt, nie jest do końca zadawalający, choć coś takiego wygląda już lepiej
plot(X1, Y1, '+b', X2, Y2, '+r')

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)

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')

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')

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,'+')

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,'+')

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