Python - wprowadzenie

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)

png

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)

png

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)

png

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)

png

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)

png

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)

png

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)

png

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)

png

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)

png

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)

png

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)

png

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)

png

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')

png

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']]