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