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, że dane nachodzące się są nadal widoczne:
plt.plot(x, y, alpha = 0.5)
plt.plot(x, y1, alpha = 0.5)
Wykres słupkowy
Często właściwą 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 skrócie "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 każdego 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, że 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