Bardzo istotną umiejętnością w Machine Learning-u jest wizualna prezentacja danych, by na tej podstawie móc wnioskować o przeróżnych aspektach różnych procesów. Dotyczy to analizy dataset-ów, wizualizacji postępu nauki, szybkiej agregacji danych. Najpopularniejszą biblioteką to tego jest Matplotlib i w tym poście opiszę najistotniejsze funkcje bazując na tym, czego sam używam. Biblioteki tej można także użyć do tworzenia interaktywnych prezentacji wyników statystycznych zarówno w analizie danych jak i np. zbierania statystyk na żywo działania systemów.
Wstęp
Wszystkie poniższe przykłady realizowane są w jupyter notebook (tutaj - informacja jak zainstalować).
By zacząć prace należy importować potrzebne biblioteki...
import matplotlib.pyplot as plt import numpy as np %matplotlib inline...i przygotować dane do pracy - tutaj działam na możliwie prostych przykładach (3 zestawy po 10 liczb):
x = np.array([1,2,3,4,5,6,7,8,9,20]) y = np.array([10,20,30,40,50,40,30,20,10,90]) y1 = np.array([12,8,34,31,55,39,30,28,15,85])Wykres liniowy - x & y
Najprostszy wykres to liniowy, podajemy współrzędne punktów na "osi X" w postaci listy i analogicznie wartości na "osi Y".
plt.plot(x, y)
Wykres liniowy - same wartości
Może się zdarzyć, ze dla serii danych interesuje nas jedynie postęp wartości (bez podawania kontekstu osi X). Wówczas na osi x dostaniemy wyliczenie wartości (od 0 do N-1).
plt.plot(y)
Wiele wykresów naraz
Kiedy chcemy umieścić wiele wykresów na sobie wystarczy wielokrotnie zawołać funkcję rysujacą.
plt.plot(x, y) plt.plot(x, y1)
Wykres punktów
Kiedy trzeba wyświetlić jedynie punkty w przestrzeni 2D bez nadawania kontekstu następowania użyjemy:
plt.scatter(x,y)
Markery wartości
Często, by wykres był bardziej czytelny, a także lepiej dostępny dla osób źle postrzegających kolory warto użyć markerów wartości - poniżej przedstawiam dwa przykłady (więcej w dokumentacji matplotlib )
plt.plot(x, y, marker='o') plt.plot(x, y1, marker='x')
Styl linii
Podobne zastosowanie jak markery może mieć rodzaj linii:
plt.plot(x, y, color='red', linestyle='--') plt.plot(x, y1, color='green', linestyle='-.')
Kanał alpha
W przypadkach kiedy liczba danych na jednym wykresie jest duża, pomocny może być kanał alpha, który sprawia, iż dane nachodzące się są przez cały czas widoczne:
plt.plot(x, y, alpha = 0.5) plt.plot(x, y1, alpha = 0.5)
Wykres słupkowy
Często adekwatną formą wykresu będzie słupkowy, wówczas kanał alpha przydaje się jeszcze bardziej.
plt.bar(x, y, alpha = 0.5) plt.bar(x, y1, alpha = 0.5)
Wykres słupkowy - łączenie wykresów - stos
Kiedy chcemy pokazać dane kumulatywnie z podziałem na składowe, przydatny będzie "stacked bar plot. Do realizacji tego efekty wykorzystana jest własność "bottom" , która oznacza od jakiej wartości drugi wykres słupkowy ma zostać rysowany.
plt.bar(x, y, alpha = 0.5) plt.bar(x, y1, alpha = 0.5, bottom = y)
Wykres słupkowy - łączenie wykresów - obok
Innym rozwiązaniem jest pokazanie wykresu słupkowego na potrzeby porównania, wówczas następujące wartości chcemy prezentować obok siebie. Do realizacji tego wykresu użyty jest trick zmniejszający szerokość każdego słupka i dodający offset do drugiej serii danych:
width = 0.33 plt.bar(x, y, width,alpha = 0.5) plt.bar(x+width, y1, width, alpha = 0.5)
Histogram
By poznać rozkład wartości zbioru, tak często potrzebny w Machine Learning-u wykorzystujemy histogram. Mamy możliwość sterowania na ile "przedziałów"(bins) zbiór ma być podzielony.
plt.hist(y,alpha = 0.5) plt.hist(y1,alpha = 0.5)
Zamiana kolorów
Gdy chcemy dopasować kolory do swoich potrzeb używamy opcji "color" bądź w uproszczeniu "c".
plt.plot(x, y, color='red') plt.plot(x, y1, c='green')
Rozmiar wykresu
Kiedy domyślny rozmiar wykresu nie pasuje do wymagań, rozmiaru rysowania można łatwo dostosować do potrzeb:
plt.figure(figsize=(10,3)) plt.plot(x, y) plt.plot(x, y1)
Legenda
By opisać wartości używamy połączenia opcji "label" dla wszystkich z wykresów i metody "legend()" odpowiedzialnej za wyrenderowanie legendy na obrazie:
plt.figure(figsize=(10,3)) plt.plot(x, y, label="Y") plt.plot(x, y1, label="Y1") plt.legend()
Wiele wykresów
Kiedy naraz potrzeba użyć wielu odseparowanych wykresów, możemy podejść to tematu iteracyjnie, za każdym razem tworząc nowy wykres ( "figure" ):
plt.figure(figsize=(10,3)) plt.plot(x, y) plt.figure(figsize=(10,3)) plt.plot(x, y1)
Wiele wykresów naraz, łączenie osi
...bądź użyć wbudowanej funkcji, która daje możliwość określenia w ilu wierszach i kolumnach chcemy rozmieścić wiele wykresów. W przykładzie 2 wiersze i 1 kolumna:
fig, axes = plt.subplots(2,1, sharex=True) axes[0].plot(x, y) axes[1].plot(x, y1)
Linie wiodące
Do celów lepszej wizualizacji często pokazać jakiś punkt odniesienia - wartość do której się dąży, bądź która ułatwia czytanie wykresu:
plt.figure(figsize=(10,3)) plt.plot(x, y, label="Y") plt.plot(x, y1, label="Y1") plt.hlines(50,0,np.max(x), colors=['black'], alpha=0.5, linestyle='--') plt.vlines(10,0,np.max(y1), colors=['black'], alpha=0.5, linestyle='--')
Zawężanie zakresu
Kiedy chcemy pokazać jakiś zakres przebiegu wykresu możemy ograniczyć, która część będzie pokazana (limit na osi x i limit na osi y):
plt.figure(figsize=(10,3)) plt.plot(x, y, label="Y") plt.plot(x, y1, label="Y1") plt.xlim(5,14) plt.ylim(8,40)
Nazwy osi
Dla lepszego zrozumienia wykresu warto tez opisać osie - często rozwiewa to pytania o to, co dokładnie jest na osiach. xlabel - legenda dla osi x, ylabel - legenda dla osi y, title dla tytuły wykresu:
plt.figure(figsize=(10,3)) plt.plot(x, y, label="Y") plt.plot(x, y1, label="Y1") plt.title("Sample of plottting @ aivision.pl") plt.xlabel("timesteps") plt.ylabel("awesomeness")
Wyłączanie rysowania osi
Z przeróżnych powodów prezentacji danych, możemy chcieć ukryć osie. (Często zdarza się tak, iż biblioteka matplotlib służy do pokazywania obrazów, gdzie dodaje oś X i Y z wartościami w pikselach, których możemy nie chcieć pokazywać.)
plt.figure(figsize=(10,3)) plt.plot(x, y, label="Y") plt.plot(x, y1, label="Y1") plt.axis('off') plt.title("Awesomeness trend")
Zapisywanie do pliku
Każdy zaprezentowany wynik można zapisać do pliku i użyć do innego zastosowania.
plt.figure(figsize=(10,3)) plt.plot(x, y, label="Y") plt.plot(x, y1, label="Y1") plt.axis('off') plt.title("Awesomeness trend") # Sprawdzamy poprawność zapisu from PIL import Image img = Image.open('filename.png') print(img.size) img
Więcej
- Oficjalna strona i dokumentacja matplotlib