08 - Biblioteka `pandas` cz. 4: wizualizacja danych
Dotychczas używaliśmy biblioteki pandas
w celu prostej selekcji i analizy danych, teraz przyszedł czas na podstawy wizualizacji danych.
Najpierw użyjemy w tym celu metod dostarczonych przez pakiet pandas
, później przyjrzymy się bliżej bibliotece matplotlib
a w końcu nieco dłużej popracujemy z seaborn
.
Poniżej przedstawię jedynie wybrane typy wykresów oferowanych przez wymienione biblioteki i niektóre możliwości ich modyfikacji.
W razie potrzeby warto się przyjrzeć im bliżej.
Zacznijmy od zaimportowania danych (patrz poprzednia lekcja) i ich lekkiej modyfikacji
import pandas as pd
dane = pd.read_csv('organelles.csv')
# Tworzymy kolumnę dla poszczególnych grup organizmów
# Zob. zadanie z poprzedniej lekcji
dane['Grupy'] = dane['Organism Groups'].str.split(';').str[1]
# Zmieniamy wartości "chloroplast" na "plastid" -
# chloroplasty to przecież plastydy
dane['Type'] = ['plastid' if row == 'chloroplast' else row for row in dane['Type']]
# Sprawdzenie wartości w kolumnie "Type"
print(dane['Type'].unique())
# Operacja groupby - grupujemy po typie organelli
# oraz grupie organizmów
grupy = dane.groupby(['Type', 'Grupy'])
['mitochondrion' 'plastid' 'apicoplast' 'kinetoplast' 'cyanelle'
'chromatophore']
Teraz obliczmy średnie i wybierzmy dane dla mitochondriów dla wybranych grup organizmów:
# Obliczamy średnie
srednie_Size = grupy[['Size(Mb)', 'Genes']].mean()
# Selekcja danych dla mitochondriów i grup organizmów:
mitochondria_Srednie_size = srednie_Size.loc['mitochondrion']\
.loc[['Animals','Fungi','Plants']]
print(mitochondria_Srednie_size)
Size(Mb) Genes
Grupy
Animals 0.016406 25.926091
Fungi 0.066471 34.237454
Plants 0.308913 71.170270
Wygenerujmy prosty wykres słupkowy z użyciem metod dostępnych dla ramki danych:
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)')
Uwaga jeśli używasz jupyter-lab
, to powyższy wykres pokaże się automatycznie. Jeśli natomiast uruchamiasz kod z zapisanego pliku z kodem Pythona powinieneś najpierw zaimportować odpowiedni moduł z biblioteki matplotlib
:
import matplotlib.pyplot as plt
a na końcu użyć polecenia:
plt.show()
Możemy zmieniać pewne parametry np. kolor wykresu:
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)', color = 'green')
Można też zastosować listę z nazwami kolorów:
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)',
color = ['red','green','blue'])
Legendę można łatwo usunąć ustawiając dodatkowy parametr (legend
):
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)',
color = ['brown','red','orange'],
legend = False)
Teraz będziemy chcieli dołożyć do wykresu słupki pokazujące odchylenie standardowe, najpierw trzeba je obliczyć:
size_sd = grupy[['Size(Mb)', 'Genes']].std()
mitochondria_Srednie_sd = size_sd.loc['mitochondrion'].loc[['Animals','Fungi','Plants']]
print(mitochondria_Srednie_sd)
Size(Mb) Genes
Grupy
Animals 0.001457 12.497448
Fungi 0.038090 26.790855
Plants 0.292444 120.637200
Stwórzmy ponownie wykres słupkowy uzupełniony o wartości odchyleń standardowych:
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)',
yerr = mitochondria_Srednie_sd['Size(Mb)'])
Wykres można także przedstawić poziomo, w takim przypadku należy użyć metody barh()
zamiast bar()
i zastosować parametr xerr
:
mitochondria_Srednie_size.plot.barh(y = 'Size(Mb)',
xerr = mitochondria_Srednie_sd['Size(Mb)'])
Możemy też z uzyskanych zestawień uzyskać łatwo wykres dla liczby genów:
mitochondria_Srednie_size.plot.bar(y = 'Genes',
yerr = mitochondria_Srednie_sd['Genes'])
Zauważ, że dolna granica odchylenia standardowego dla roślin sięga znacznie poniżej 0
.
Sprawdźmy, jak wygląda rozkład wartości liczby opisanych genów dla mitochondriów roślinnych.
W tym celu przyda nam się histogram.
Najpierw dokonajmy selekcji danych:
# Selekcja danych dla mitochondriów roślinnych:
mitochondria_roslinne = dane[(dane['Type'] == 'mitochondrion')
& (dane['Grupy'] == 'Plants')]
Utwórzmy teraz histogram.
W tym celu użyjemy metody hist()
podając wartość bins
, która określa interwały wartości.
mitochondria_roslinne['Genes'].plot.hist(bins=100)
Jak widać, są genomy o bardzo wysokiej liczbie genów (lub genom). Możemy łatwo sprawdzić ile ich jest, jakich organizmów dotyczą i ile mają opisanych genów:
# Selekcja danych dla mitochondriów roślinnych:
mit_rosl_duzo_genow = dane[(dane['Type'] == 'mitochondrion')
& (dane['Grupy'] == 'Plants')
& (dane['Genes'] > 500)]
print(mit_rosl_duzo_genow[['Organism Name', 'Genes', 'Replicons']])
Organism Name Genes Replicons
18287 Utricularia reniformis 2299 NC_034982.1/KY774314.1
Jak widać, jest to jeden organizm, który znacznie odstaje od pozostałych.
Można znaleźć w bazie GenBank
dane tego genomu używając np. numeru dostępowego, który widzimy w kolumnie Replicons
: https://www.ncbi.nlm.nih.gov/nuccore/NC_034982.
Przyjrzyjmy się dokładniej niższym wartościom, w tym celu wybierzmy genomy o liczbie opisanych genów do 500:
# Selekcja danych dla mitochondriów roślinnych:
mit_rosl_reszta = dane[(dane['Type'] == 'mitochondrion')
& (dane['Grupy'] == 'Plants')
& (dane['Genes'] <= 500)]
mit_rosl_reszta['Genes'].plot.hist(bins=500)
Widać, że są tu genomy, dla których nie opisano w ogóle genów lub opisano ich kilka. Odrzućmy te najniższe wartości:
# Selekcja danych dla mitochondriów roślinnych:
mit_rosl_wybrane = dane[(dane['Type'] == 'mitochondrion')
& (dane['Grupy'] == 'Plants')
& (dane['Genes'] <= 500)
& (dane['Genes'] > 10)]
mit_rosl_wybrane['Genes'].plot.hist(bins=500)
Stwórzmy teraz histogram pokazujący jak liczne są genomy w poszczególnych zakresach wielkości. Najpierw wybierzmy dane:
# Selekcja danych dla mitochondriów roślinnych:
mitochondria_roslinne = dane[(dane['Type'] == 'mitochondrion')
& (dane['Grupy'] == 'Plants')]
Teraz użyjemy metody hist
:
mitochondria_roslinne['Size(Mb)'].plot.hist(bins=100)
Powyżej pokazałem pewne możliwości, choć nie wszystkie, modyfikacji wykresów.
Więcej można osiągnąć wspierając się biblioteką matplotlib
, której się niebawem przyjrzyjmy bliżej.
Na razie wykorzystajmy ją do modyfikacji wykresów uzyskanych dzięki metodom ramki danych.
Zacznijmy od odtworzenia jednego z wcześniejszych wykresów, ale najpierw odpowiednio wybierzmy dane.
# Obliczamy średnie
srednie_Size = grupy[['Size(Mb)', 'Genes']].mean()
# Selekcja danych dla mitochondriów i grup organizmów:
mitochondria_Srednie_size = srednie_Size.loc['mitochondrion']\
.loc[['Animals','Fungi','Plants']]
print(mitochondria_Srednie_size)
Size(Mb) Genes
Grupy
Animals 0.016406 25.926091
Fungi 0.066471 34.237454
Plants 0.308913 71.170270
- Teraz wykres:
# Obliczamy średnie
srednie_Size = grupy['Size(Mb)'].mean()
# Selekcja danych dla mitochondriów i grup organizmów:
mitochondria_Srednie_size = srednie_Size.loc['mitochondrion']\
.loc[['Animals','Fungi','Plants']]
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)', legend = False)
Zaimportujmy teraz odpowiedni moduł z biblioteki matplotlib
i dodajmy tytuł, własne opisy osi, własne opisy słupków oraz zapiszmy plik w formacie pdf:
# Import modułu z matplotlib
from matplotlib import pyplot as plt
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)', legend = False)
plt.title('Rozmiary genomów mitochondrialnych', fontsize=14)
# Opis osi x
plt.xlabel('organizmy',fontsize=12)
# Opis osi y
plt.ylabel('Rozmiar genomu (Mb)',fontsize=12)
# Opisy słupków
plt.xticks([0, 1, 2],['Zwierzęta', 'Grzyby', 'Rośliny'])
# Zapis pliku
plt.savefig('rozmiar_mitochondriow.pdf', bbox_inches='tight')
Oczywiście nie wyczerpaliśmy możliwości oferowanych bezpośrednio przez bibliotekę pandas
, więcej na ten temat można poczytać np. w dokumentacji
Teraz jednak przejdziemy do bardziej zaawansowanej biblioteki służącej wizualizacji: matplotlib
.
Biblioteka matplotlib
Z biblioteką matplotlib
spotkaliśmy się już w pierwszej części kursu, kiedy użyliśmy jej do utworzenia prostych wykresów na podstawie wygenerowanych danych. Teraz użyjemy jej do wizualizacji danych analizowanych z pomocą biblioteki pandas
.
Jeżeli to konieczne, zacznijmy od importu i wstępnych modyfikacji danych:
import pandas as pd
# Import danych, parsujemy kolumnę Release Date do typu datetime64
dane = pd.read_csv('organelles.csv', parse_dates = ['Release Date'])
# Tworzymy kolumnę dla poszczególnych grup organizmów
# Zob. zadanie z poprzedniej lekcji
dane['Grupy'] = dane['Organism Groups'].str.split(';').str[1]
# Zmieniamy wartości "chloroplast" na "plastid" -
# chloroplasty to przecież plastydy
dane['Type'] = ['plastid' if row == 'chloroplast' else row for row in dane['Type']]
Teraz odtwórzmy wykres słupkowy obrazujący wielkość genomów mitochondriów u zwierząt, grzybów i roślin:
# Import modułu z matplotlib
from matplotlib import pyplot as plt
# Obliczamy średnie
srednie_Size = grupy['Size(Mb)'].mean()
# Selekcja danych dla mitochondriów i grup organizmów:
mitochondria_Srednie_size = srednie_Size.loc['mitochondrion']\
.loc[['Animals','Fungi','Plants']]
print(mitochondria_Srednie_size)
plt.bar(mitochondria_Srednie_size.index,
mitochondria_Srednie_size)
plt.title('Rozmiary genomów mitochondrialnych', fontsize=14)
# Opis osi x
plt.xlabel('organizmy',fontsize=12)
# Opis osi y
plt.ylabel('Rozmiar genomu (Mb)',fontsize=12)
# Opisy słupków
plt.xticks([0, 1, 2],['Zwierzęta', 'Grzyby', 'Rośliny'])
Grupy
Animals 0.016406
Fungi 0.066471
Plants 0.308913
Name: Size(Mb), dtype: float64
Poszczególne słupki można pokolorować:
plt.bar(mitochondria_Srednie_size.index,
mitochondria_Srednie_size,
color = ['brown', 'red', 'darkorange'])
plt.title('Rozmiary genomów mitochondrialnych', fontsize=14)
# Opis osi x
plt.xlabel('organizmy',fontsize=12)
# Opis osi y
plt.ylabel('Rozmiar genomu (Mb)',fontsize=12)
# Opisy słupków
plt.xticks([0, 1, 2],['Zwierzęta', 'Grzyby', 'Rośliny'])
Stwórzmy teraz kolumnę zawierająca wyłącznie rok publikacji genomów:
dane['Rok'] = dane['Release Date'].dt.year
print(dane['Rok'].unique())
[2018 2013 2009 2016 2020 2015 2014 2019 2017 2021 2011 2008 2004 2007
1994 2006 2012 2010 2003 2005 2002 1999 1996 2001 2000 1998 1997 1995
1993 1986 1989 1990]
Zgrupujmy dane wg. typu i roku. Sprawdźmy ile zostało opublikowanych genomów mitochondrialnych w poszczególnych latach:
lata = dane.groupby(['Type', 'Rok'])
lata_liczba = lata.count()
print(lata_liczba.loc['mitochondrion']['Size(Mb)'])
Rok
1990 3
1993 2
1994 3
1995 1
1996 1
1997 1
1998 3
1999 94
2000 45
2001 105
2002 92
2003 91
2004 185
2005 126
2006 275
2007 203
2008 317
2009 425
2010 281
2011 405
2012 515
2013 886
2014 1016
2015 1203
2016 1097
2017 1131
2018 1021
2019 1018
2020 1210
2021 557
Name: Size(Mb), dtype: int64
Przedstawmy te dane na wykresie:
plt.plot(lata_liczba.loc['mitochondrion']['Size(Mb)'])
plt.title('Liczba opublikowanych genomów mitochondrialnych w latach ', fontsize=12)
# Opis osi x
plt.xlabel('Lata',fontsize=10)
# Opis osi y
plt.ylabel('L. opubl. genomów mitochondrialnych',fontsize=10)
Text(0, 0.5, 'L. opubl. genomów mitochondrialnych')
Teraz pogrupujmy dodatkowo dane wg. grup organizmów a następnie umieśćmy na wykresie dane dla mitochondriów zwierzęcych i roślinnych:
lata = dane.groupby(['Grupy','Type', 'Rok'])
lata_liczba = lata.count()['Size(Mb)']
print(lata_liczba)
Grupy Type Rok
Animals mitochondrion 1998 2
1999 88
2000 32
2001 96
2002 85
..
Protists plastid 2017 4
2018 17
2019 16
2020 2
2021 1
Name: Size(Mb), Length: 204, dtype: int64
# Wykres dla zwierząt, dodajemy etykietę
plt.plot(lata_liczba.loc['Animals'].loc['mitochondrion'],
label='Zwierzęta')
# Wykres dla roślin, dodajemy etykietę
plt.plot(lata_liczba.loc['Plants'].loc['mitochondrion'],
label='Rośliny')
plt.title('Liczba opublikowanych genomów mitochondrialnych w latach ', fontsize=12)
# Opis osi x
plt.xlabel('Lata',fontsize=10)
# Opis osi y
plt.ylabel('L. opubl. genomów',fontsize=10)
# Dodanie legendy
plt.legend()
Oczywiście można zmieniać różne parametry wykresu, takie jak styl i kolor:
# Wykres dla zwierząt
plt.plot(lata_liczba.loc['Animals'].loc['mitochondrion'],
'-.b', # styl i kolor linii: kropka, kreska - niebieska
label='Zwierzęta')
# Wykres dla roślin
plt.plot(lata_liczba.loc['Plants'].loc['mitochondrion'],
'--ro', # styl i kolor linii: linia przerywana z punktami, czerwona
label='Rośliny')
plt.title('Liczba opublikowanych genomów mitochondrialnych w latach ',
fontsize=12)
# Opis osi x
plt.xlabel('Lata',fontsize=10)
# Opis osi y
plt.ylabel('L. opubl. genomów',fontsize=10)
# Dodanie legendy
plt.legend()
Możliwych jest wiele innych modyfikacji, warto przejrzeć dokumentację.
Teraz pogrupujmy dane wg. typu organelli i organizmów.
organelle = dane.groupby(['Type', 'Grupy'])
organelle_liczba = organelle.count()['Size(Mb)']
print(organelle_liczba)
Type Grupy
apicoplast Protists 61
chromatophore Protists 2
cyanelle Protists 1
kinetoplast Protists 3
mitochondrion Animals 10770
Fungi 817
Other 159
Plants 370
Protists 196
plastid Other 193
Plants 6161
Protists 79
Name: Size(Mb), dtype: int64
Następnie utwórzmy wykres kołowy z kilkoma ozdobnikami:
plt.pie(organelle_liczba.loc['mitochondrion'],
# etykiety
labels=organelle_liczba.loc['mitochondrion'].index,
# Wyświetlenie wartości % do dwu miejsc po przecinku
autopct = '%1.2f%%',
# cień
shadow = True,
# rozsunięcie wycinków
explode = (0.1, 0.2, 0.3, 0.4, 0.5))
plt.title('Liczby genomów mitochondrialnych grup organizmów')
Biblioteka seaborn
Nieco więcej czasu i uwagi poświęcimy bibliotece seaborn
, która zresztą bazuje na matplotlib
ale poszerza jej możliwości a także pozwala uzyskać bardziej estetyczne wizualizacje danych (choć to rzecz gustu).
Jeśli to konieczne wczytaj ponownie dane:
import pandas as pd
# Import danych, parsujemy kolumnę Release Date do typu datetime64
dane = pd.read_csv('organelles.csv', parse_dates = ['Release Date'])
# Tworzymy kolumnę dla poszczególnych grup organizmów
# Zob. zadanie z poprzedniej lekcji
dane['Grupy'] = dane['Organism Groups'].str.split(';').str[1]
# Zmieniamy wartości "chloroplast" na "plastid" -
# chloroplasty to przecież plastydy
dane['Type'] = ['plastid' if row == 'chloroplast' else row for row in dane['Type']]
dane['Rok'] = dane['Release Date'].dt.year
Zacznijmy od odtworzenia znanego nam wykresu słupkowego, tym razem używając seaborn
:
# Import seaborn
import seaborn as sns
# Import modułu z matplotlib
from matplotlib import pyplot as plt
# Obliczamy średnie
srednie_Size = grupy.mean()['Size(Mb)']
# Selekcja danych dla mitochondriów i grup organizmów:
mitochondria_Srednie_size = srednie_Size.loc['mitochondrion']\
.loc[['Animals','Fungi','Plants']]
print(mitochondria_Srednie_size)
sns.barplot(x = mitochondria_Srednie_size.index,
y = mitochondria_Srednie_size)
Grupy
Animals 0.016406
Fungi 0.066471
Plants 0.308913
Name: Size(Mb), dtype: float64
Jak widać, domyślnie słupki mają różne kolory. Można je oczywiście dostosować. Jednym ze sposobów jest zastosowanie palet:
sns.barplot(x = mitochondria_Srednie_size.index,
y = mitochondria_Srednie_size,
palette = 'CMRmap_r')
Więcej na temat palet można poczytać m. in w dokumentacji a także np. tutaj. Listę dostępnych nazw palet można uzyskać podając nazwę, która nie jest nazwą żadnej palety, wtedy pojawi się informacja o błędzie zawierająca m. in. wymienione dostępne nazwy palet:
sns.barplot(x = mitochondria_Srednie_size.index,
y = mitochondria_Srednie_size,
palette = 'Nie_ma_takiej_palety')
...
ValueError: 'Nie_ma_takiej_palety' is not a valid value for name;
supported values are 'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG',
'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r',
'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys',
'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r',
'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r',
'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr',
'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r',
'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn',
'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3'
, 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn',
'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd',
'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary',
'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper',
'copper_r', 'crest', 'crest_r', 'cubehelix', 'cubehelix_r',
...
Poniżej wykorzystamy niektóre z nich.
Można też podać wybrane kolory:
sns.barplot(x = mitochondria_Srednie_size.index,
y = mitochondria_Srednie_size,
palette = ['brown', 'red', 'darkorange'])
Możemy też ustawić styl, który wpływa m.in. na tło wykresu:
sns.set_style('whitegrid')
sns.barplot(x = mitochondria_Srednie_size.index,
y = mitochondria_Srednie_size,
palette = 'CMRmap_r')
sns.set_style('dark')
sns.barplot(x = mitochondria_Srednie_size.index,
y = mitochondria_Srednie_size,
palette = 'CMRmap_r')
sns.set_style('darkgrid')
sns.barplot(x = mitochondria_Srednie_size.index,
y = mitochondria_Srednie_size,
palette = 'CMRmap_r')
Ustawmy teraz tytuł, opisy osi i podpisy pod słupkami:
sns.set_style('darkgrid')
sns.barplot(x = mitochondria_Srednie_size.index,
y = mitochondria_Srednie_size,
palette = 'CMRmap_r')
plt.title('Rozmiary genomów mitochondrialnych', fontsize=14)
# Opis osi x
plt.xlabel('organizmy',fontsize=12)
# Opis osi y
plt.ylabel('Rozmiar genomu (Mb)',fontsize=12)
# Opisy słupków
plt.xticks([0, 1, 2],['Zwierzęta', 'Grzyby', 'Rośliny'])
Wybierzmy teraz ponownie zestaw danych do dalszych analiz, tym razem nie grupując ich. Pozwoli nam to m.in. dokładniej przyjrzeć się rozkładowi wartości.
mito = dane[ (dane['Grupy'].isin(['Animals','Fungi','Plants']))
& (dane['Type'] == 'mitochondrion')
& (dane['Genes'] <= 500)
& (dane['Genes'] > 10)
]
print(mito['Genes'])
0 37
1 35
2 13
3 37
4 37
..
18803 37
18805 67
18808 40
18809 35
18811 43
Name: Genes, Length: 11393, dtype: int64
Utwórzmy wykres słupkowy z zaznaczeniem odchylenia standardowego:
sns.barplot(data = mito,
x = 'Grupy',
y = 'Size(Mb)',
palette = 'RdBu',
# Słupki błędu wyznaczające odchylenie standardowe
errorbar='sd')
Jeśli nie podamy wartości parametru ci
domyślnie rysowany jest 95% zakres ufności dla średniej liczony za pomocą metody bootstrap:
sns.barplot(data = mito,
x = 'Grupy',
y = 'Size(Mb)',
palette = 'cividis')
Można też podać własny zakres ufności:
sns.barplot(data = mito,
x = 'Grupy',
y = 'Size(Mb)',
palette = 'cool',
# Słupki błędu wyznaczające przedział ufności
errorbar=('ci', 99))
Do słupków błędu można dodać poprzeczne linie a także zmienić ich grubość:
sns.barplot(data = mito,
x = 'Grupy',
y = 'Size(Mb)',
# Linie poprzeczne na słupkach
capsize = 0.2,
# Grubość linii na słupkach będu
errwidth = 5,
palette = 'dark')
Sprawdźmy jaką wielkość mają poszczególne genomy, w grupach organizmów. W tym celu wykorzystamy kolejny typ wykresu:
sns.set_style('whitegrid')
sns.catplot(data = mito,
x = 'Grupy',
y = 'Size(Mb)',
palette = 'afmhot_r',
hue = 'Grupy')
W powyższym przykładzie argument hue
służy do określenia danych, które będą użyte do kolorowania. Tu każda z grup otrzyma oddzielny kolor. Sprawdź jak zmieni się wykres jeśli zamiast Grupy
użyjesz Size(Mb)
albo Genes
. Wrócimy jeszcze do tego zagadnienia.
Sprawdźmy jeszcze liczby genów (ucięliśmy skrajne wartości przy selekcji danych):
sns.catplot(data = mito,
x = 'Grupy',
y = 'Genes',
palette = 'copper',
hue = 'Grupy'
)
Możemy ustawić parametr kind = 'box
aby uzyskać wykres pudełkowy.
O tym, jak go interpretować można przeczytać np. tu.
sns.catplot(data = mito,
x = 'Grupy',
y = 'Genes',
kind = 'box',
palette = 'autumn')
Z kolei wykres wiolinowy uzyskamy ustawiając kind = violin
(tym razem użyjemy kolumny GC%
):
sns.catplot(data = mito,
x = 'Grupy',
y = 'GC%',
kind = 'violin',
palette = 'brg')
Można też użyć parametru kind
do uzyskania wykresu słupkowego:
sns.catplot(data = mito,
x = 'Grupy',
y = 'Size(Mb)',
kind = 'bar',
capsize = 0.1,
palette = 'coolwarm')
Sprawdźmy teraz jak rozłożone są wartości wielkości genomów i liczby genów u zwierząt i roślin:
sns.relplot(data = mito[mito['Grupy'].isin(['Animals','Plants'])],
x = 'Genes',
y = 'Size(Mb)',
# Grupy organizmów traktowane oddzielnie - w różnych kolorach
hue = 'Grupy',
# Wysokość wykresu (w calach)
height = 6,
# Proporcja szerokości do wysokości:
# height * aspect
aspect = 2,
palette = 'cubehelix',
alpha = 0.5 # przeźroczystość
)
Ten typ wykresu pozwala także zróżnicować wielkość kół, w zależności od wartości:
sns.relplot(data = mito[mito['Grupy'].isin(['Animals','Plants'])],
x = 'Genes',
y = 'Size(Mb)',
hue = 'Grupy',
# Wysokość wykresu (w calach)
height = 6,
aspect = 2,
# Wartości zestawu danych wyrażone w wielkości symboli (tu: kółek)
size = 'Pseudogene',
# Zakres wielkości symboli
sizes = (10, 300),
palette = 'flare',
alpha = 0.5)
Ustawienie parametru kind = 'line'
pozwala uzyskać wykres liniowy.
Można uzyskać przy tym przedział ufności lub odchylenie standardowe dla wartości ustawiając odpowiednio parametr ci
(zob. powyżej).
Sprawdźmy na przykład liczby genów opisywanych dla genomów mitochondrialnych roślin, zwierząt i grzybów w ostatnich 12 latach wraz z odchyleniami standardowymi.
sns.relplot(data = mito[(mito['Rok'] > pd.Timestamp.now().year-12)
& mito['Grupy'].isin(['Plants', 'Animals', 'Fungi'])],
x = 'Rok',
y = 'Genes',
hue = 'Grupy',
height = 6,
aspect = 2,
kind = 'line',
errorbar='sd',
palette = 'gnuplot2')
Parametr hue
pozwala także na przedstawienie na innych typach wykresów kilku serii danych.
Utwórzmy na przykład wykres słupkowy przedstawiający średnią liczbę genów opisanych dla genomów mitochondrialnych opublikowanych w ostatnim dziesięcioleciu, wliczając bieżący rok:
sns.catplot(data = mito[mito['Rok'] > pd.Timestamp.now().year-5],
x = 'Rok',
y = 'Size(Mb)',
hue = 'Grupy',
kind = 'bar',
height = 6,
aspect = 2,
palette = 'Oranges_r')
Dystrybucję wartości można zwizualizować za pomocą m.in. funkcji displot()
, argument kde = True
powoduje wygenerowanie krzywej dopasowanej do wartości z użyciem jądrowego estymatora gęstości - KDE (ang. kernel density estimation).
dane = mito[(mito['Rok'] > pd.Timestamp.now().year-5)
& mito['Grupy'].isin(['Fungi', 'Plants'])]
sns.displot(dane,
x = 'Genes',
kde = True,
hue = 'Grupy',
palette = 'viridis')
Kilka serii danych można także przedstawić w postaci serii wykresów np. z użyciem argumentu col
:
sns.catplot(data = mito[mito['Rok'] > pd.Timestamp.now().year-5],
x = 'Rok',
y = 'Size(Mb)',
col = 'Grupy',
kind = 'bar',
errorbar=('ci', False),
col_order=['Animals', 'Fungi', 'Plants'],
height = 4,
aspect = 1,
palette = 'dark')
Klasa FacetGrid
pozwala na tworzenie zestawu wykresów z użyciem zmiennych.
Poniżej przykład zestawienia wartości rozmiarów genomów i liczby opisanych genów w mitochondriach, dla grzybów i roślin w latach 2018-2020 (zwróć uwagę na metodę between()
).
# Import modułu z matplotlib
from matplotlib import pyplot as plt
# Selekcja danych: metoda between() pozwala wybrać wartości
# wg. wskazanego zakresu
dane = mito[(mito['Rok'].between(2018, 2020))
& mito['Grupy'].isin(['Fungi', 'Plants'])]
f = sns.FacetGrid(data = dane,
row = 'Grupy', # Wartości w kolejnych rzędach
col='Rok', # Wartości w kolejnych kolumnach
height = 4, aspect = 1)
f = f.map(plt.scatter, # typ wykresu
'Genes','Size(Mb)')
Możemy też wykresy umieścić w jednym rzędzie a wartości dla grzybów i roślin. Przy okazji poznamy sposób modyfikacji poszczególnych wykresów, tu dodamy do nich legendy:
dane = mito[(mito['Rok'].between(2018, 2020))
& mito['Grupy'].isin(['Fungi', 'Plants'])]
f = sns.FacetGrid(data = dane,
col = 'Rok',
hue = 'Grupy',
height = 4,
aspect = 1,
palette = 'gnuplot2')
f = f.map(plt.scatter,
'Genes', 'Size(Mb)',
alpha=0.2
)
# Poszczególne wykresy są przechowywane w obiekcie typu ndarray
# metoda ravel() zwraca "spłaszczony", jednowymiarowy obiekt
# ndarray, który możemy iterować, np. w celu modyfikacji
# wykresów
for ax in f.axes.ravel():
ax.legend() #Dodajemy legendę
Zadanie
- Zbadaj, jak w ciągu ostatnich 10 lat zmieniła się liczba umieszczonych genomów mitochondrialnych dla różnych grup zwierząt.
- Porównaj wielkość genomu mitochondrialnego i liczbę opisanych genów w różnych grupach zwierząt.