Pandas - wizualizacja danych
import matplotlib.pyplot as plt
def save_fig(figNumber):
outPDF = 'fig_wizualizacja/figure_{}.pdf'.format(figNumber)
plt.savefig(outPDF, bbox_inches='tight')
figNumber += 1
return figNumber
figNumber=1
Dotychczas używaliśmy biblioteki pandas
w celu prostej selekcji i analizy danych, teraz przyszedł czas na podstawy wizualizacji danych.
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.mean()[['Size(Mb)', 'Genes']]
# 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)')
figNumber = save_fig(figNumber)
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')
figNumber = save_fig(figNumber)
Można też zastosować listę z nazwami kolorów:
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)',
color = ['red','green','blue'])
figNumber = save_fig(figNumber)
Legende można łatwo usunąć ustawiając dodatkowy parametr (legend
):
mitochondria_Srednie_size.plot.bar(y = 'Size(Mb)',
color = ['brown','red','orange'],
legend = False)
figNumber = save_fig(figNumber)
Teraz będziemy chcieli dołożyć do wykresu słupki pokazujące odchylenie standardowe, najpierw trzeba je obliczyć:
size_sd = grupy.std()[['Size(Mb)', 'Genes']]
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óżmy 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)'])
figNumber = save_fig(figNumber)
Wykres można także przedstawić poziomo, w takim przypadku należy użyć metody barh()
zmiast bar()
i zastosowac parametr xerr
:
mitochondria_Srednie_size.plot.barh(y = 'Size(Mb)',
xerr = mitochondria_Srednie_sd['Size(Mb)'])
figNumber = save_fig(figNumber)
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'])
figNumber = save_fig(figNumber)
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óżmy teraz histogram.
W tym celu uzyjemy metody hist()
podając wartość bins
, która określa interwały wartości.
mitochondria_roslinne['Genes'].plot.hist(bins=100)
figNumber = save_fig(figNumber)
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_genów = dane[(dane['Type'] == 'mitochondrion')
& (dane['Grupy'] == 'Plants')
& (dane['Genes'] > 500)]
print(mit_rosl_duzo_genów[['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 pozostalych.
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)
figNumber = save_fig(figNumber)
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)
figNumber = save_fig(figNumber)
Utwóżmy 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)
figNumber = save_fig(figNumber)
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.
Zacznimy od odtworzenia jednego z wcześniejszych wykresów:
# Obliczamy średnie
srednie_Size = grupy.mean()[['Size(Mb)', 'Genes']]
# 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
# Obliczamy średnie
srednie_Size = grupy.mean()[['Size(Mb)', 'Genes']]
# 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)
figNumber = save_fig(figNumber)
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 zaawansowanych bibliotek służących wizualizacji: matplotlib
i seaborn
.
Biblioteka matplotlib
Jeżeli to konieczne, zacznimy od importu i wstępnych modyfikacji danych:
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']]