Heatmap avec dendrogramme en Python + matplotlib

Dans R, vous pouvez dessiner une carte thermique avec un dendrogramme regroupé pour chaque axe de x et y en tapant simplement heat map (x), et le niveau d'expression des gènes est familier aux bioinformaticiens qui marmonnent tous les jours. C'est une fonction de, mais quand j'ai essayé de faire la même chose dans l'environnement Python + matplotlib, il n'y avait pas beaucoup d'informations, donc je l'ai essayé par essais et erreurs.

Je le publierai sous forme de mémorandum.

Préparation des données

Tout d'abord, en tant que données appropriées, créez des données qui montrent l'augmentation ou la diminution du niveau d'expression génique pour chaque tissu cellulaire. Les choix de tissus et de gènes ici sont tous appropriés. Nous allons modifier les données générées aléatoirement en un objet pandas.DataFrame afin qu'il lui ressemble une fois mis en cluster plus tard.

python


#!/usr/bin/env python3

genes = [
    'HIST1H4H', 'SPRN', 'DNLZ', 'PYCARD', 'PRDM11', 'DKKL1', 'CYBRD1', 'DMAP1',
    'MT1E', 'PDGFRL', 'SERTM1', 'PIFO', 'FAM109A', 'ST5', 'ABCA7', 'FAM160A1',
    'SAMD15', 'NUAK1', 'GLTP', 'HIST3H2A', 'SCN5A', 'PNPLA5', 'SFRP5', 'CCBE1',
    'PTCD1', 'RFTN1', 'SYTL2', 'FAM65B', 'NFKBIZ', 'RHOG', 'KIF3A', 'DYRK1B',
    'NXPH2', 'APLN', 'ZNF526', 'NRIP3', 'KCNMA1', 'MTSS1', 'ZNF566', 'TNC',
    'GPX2', 'AQP3', 'TSACC', 'SNX15', 'TRIM22', 'THAP6', 'GRIP1', 'DLGAP3',
]
tissues = [
    'brain', 'kidney', 'lung', 'heart',
    'liver', 'pancreas', 'testis', 'placenta',
]


def draw_heatmap(a):
    print(a.head())

def _main():
    from random import choice
    import numpy as np
    from pandas import DataFrame
    v = np.random.random([4, len(tissues)]) * 1.2 - 0.6
    w = np.random.random([3, len(genes)]) * 0.8 - 0.4
    v = np.vstack([choice(v) for x in genes])
    w = np.vstack([choice(w) for x in tissues]).T
    a = DataFrame(v + w, index=genes, columns=tissues)
    draw_heatmap(a)

if __name__ == '__main__':
    _main()

Résultat d'exécution


             brain    kidney      lung     heart     liver  pancreas  \
HIST1H4H -0.085630  0.074054  0.058026 -0.142751 -0.767515 -0.348885   
SPRN     -0.424203  0.251821 -0.012052 -0.037645 -0.000477  0.714727   
DNLZ      0.372402  0.532086  0.097971 -0.102806 -0.727570  0.109148   
PYCARD   -0.561378  0.114647  0.706732  0.681139  0.718306  0.577552   
PRDM11   -0.698969 -0.022945  0.240133  0.214540  0.251708  0.439960   

            testis  placenta  
HIST1H4H  0.324709 -0.319531  
SPRN     -0.815679 -0.010529  
DNLZ      0.402956 -0.241284  
PYCARD   -0.728135  0.077015  
PRDM11   -0.773637  0.031513  

A partir de maintenant, nous ne jouerons qu'avec la fonction draw_heatmap (a).

Pour un affichage rapide

Si vous voulez vérifier uniquement les données pour le moment, au lieu de créer des matériaux, vous pouvez les afficher en insérant les données dans ʻimshow () de matplotlib` comme suit.

def draw_heatmap(a):
    from matplotlib import pyplot as plt
    plt.imshow(a, aspect='auto', interpolation='none')
    plt.colorbar()
    plt.xticks(range(a.shape[1]), a.columns)
    plt.yticks(range(a.shape[0]), a.index)
    plt.show()

fig01.png

Faites-le bien paraître

Nous allons le faire paraître un peu mieux que l'exemple ci-dessus.

from matplotlib.colors import LinearSegmentedColormap
microarray_cmap = LinearSegmentedColormap('microarray', {
    'red': [(0.0, 1.0, 1.0), (0.5, 0.2, 0.2), (1.0, 0.0, 0.0)],
    'green': [(0.0, 0.0, 0.0), (0.5, 0.2, 0.2), (1.0, 1.0, 1.0)],
    'blue': [(0.0, 0.0, 0.0), (0.5, 0.2, 0.2), (1.0, 0.0, 0.0)],
})

def draw_heatmap(a, cmap=microarray_cmap):
    from matplotlib import pyplot as plt
    plt.imshow(a, aspect='auto', interpolation='none',
               cmap=cmap, vmin=-1.0, vmax=1.0)
    plt.colorbar()
    plt.xticks(range(a.shape[1]), a.columns, rotation=15)
    plt.yticks(range(a.shape[0]), a.index, size='small')
    plt.gca().get_xaxis().set_ticks_position('none')
    plt.gca().get_yaxis().set_ticks_position('none')
    plt.show()

fig02.png

La palette de couleurs qui passe du rouge au noir au vert n'est pas dans le préréglage de matplotlib, donc je la définis moi-même avec LinearSegmentedColormap. Si 0 est complètement noir, la différence proche de 0 est trop faible en luminosité pour être comprise, alors j'ose faire le gris foncé moyen.

Grappe

Il est plus facile de voir en regroupant des gènes avec des modèles d'expression similaires.

def draw_heatmap(a, cmap=microarray_cmap):
    from matplotlib import pyplot as plt
    from scipy.spatial.distance import pdist
    from scipy.cluster.hierarchy import linkage, dendrogram

    metric = 'euclidean'
    method = 'average'

    plt.subplot(1, 2, 1)
    ylinkage =linkage(pdist(a, metric=metric), method=method, metric=metric)
    ydendro = dendrogram(ylinkage, orientation='right', no_labels=True,
                         distance_sort='descending')
    a = a.ix[[a.index[i] for i in ydendro['leaves']]]

    plt.subplot(1, 2, 2)
    plt.imshow(a, aspect='auto', interpolation='none',
               cmap=cmap, vmin=-1.0, vmax=1.0)
    plt.colorbar()
    plt.xticks(range(a.shape[1]), a.columns, rotation=15)
    plt.yticks(range(a.shape[0]), a.index, size='small')
    plt.gca().xaxis.set_ticks_position('none')
    plt.gca().yaxis.set_ticks_position('none')
    plt.gca().invert_yaxis()
    plt.show()

Utilisez la fonction Scipy pour effectuer un regroupement hiérarchique et dessinez côte à côte avec le dendrogramme.

fig03.png

Faites-le bien paraître

Rend l'exemple ci-dessus beau.

def draw_heatmap(a, cmap=microarray_cmap):
    from matplotlib import pyplot as plt
    from mpl_toolkits.axes_grid1 import make_axes_locatable
    from scipy.spatial.distance import pdist
    from scipy.cluster.hierarchy import linkage, dendrogram

    metric = 'euclidean'
    method = 'average'

    main_axes = plt.gca()
    divider = make_axes_locatable(main_axes)

    plt.sca(divider.append_axes("left", 1.0, pad=0))
    ylinkage = linkage(pdist(a, metric=metric), method=method, metric=metric)
    ydendro = dendrogram(ylinkage, orientation='right', no_labels=True,
                         distance_sort='descending',
                         link_color_func=lambda x: 'black')
    plt.gca().set_axis_off()
    a = a.ix[[a.index[i] for i in ydendro['leaves']]]

    plt.sca(main_axes)
    plt.imshow(a, aspect='auto', interpolation='none',
               cmap=cmap, vmin=-1.0, vmax=1.0)
    plt.colorbar(pad=0.15)
    plt.gca().yaxis.tick_right()
    plt.xticks(range(a.shape[1]), a.columns, rotation=15, size='small')
    plt.yticks(range(a.shape[0]), a.index, size='small')
    plt.gca().xaxis.set_ticks_position('none')
    plt.gca().yaxis.set_ticks_position('none')
    plt.gca().invert_yaxis()
    plt.show()

fig04.png

L'axe des x est également groupé.

Ce n'est pas nécessaire pour les données chronologiques, mais il peut être plus facile de comprendre si l'axe des x est également regroupé pour les données de chaque organisation. Ce que vous faites est fondamentalement le même qu'avant.

def draw_heatmap(a, cmap=microarray_cmap):
    from matplotlib import pyplot as plt
    from mpl_toolkits.axes_grid1 import make_axes_locatable
    from scipy.spatial.distance import pdist
    from scipy.cluster.hierarchy import linkage, dendrogram

    metric = 'euclidean'
    method = 'average'

    main_axes = plt.gca()
    divider = make_axes_locatable(main_axes)
    xdendro_axes = divider.append_axes("top", 0.5, pad=0)
    ydendro_axes = divider.append_axes("left", 1.0, pad=0)

    plt.sca(xdendro_axes)
    xlinkage = linkage(pdist(a.T, metric=metric), method=method, metric=metric)
    xdendro = dendrogram(xlinkage, orientation='top', no_labels=True,
                         distance_sort='descending',
                         link_color_func=lambda x: 'black')
    plt.gca().set_axis_off()
    a = a[[a.columns[i] for i in xdendro['leaves']]]

    plt.sca(ydendro_axes)
    ylinkage = linkage(pdist(a, metric=metric), method=method,
                       metric=metric)
    ydendro = dendrogram(ylinkage, orientation='right', no_labels=True,
                         distance_sort='descending',
                         link_color_func=lambda x: 'black')
    plt.gca().set_axis_off()
    a = a.ix[[a.index[i] for i in ydendro['leaves']]]

    plt.sca(main_axes)
    plt.imshow(a, aspect='auto', interpolation='none',
               cmap=cmap, vmin=-1.0, vmax=1.0)
    plt.colorbar(pad=0.15)
    plt.gca().yaxis.tick_right()
    plt.xticks(range(a.shape[1]), a.columns, rotation=15, size='small')
    plt.yticks(range(a.shape[0]), a.index, size='x-small')
    plt.gca().xaxis.set_ticks_position('none')
    plt.gca().yaxis.set_ticks_position('none')
    plt.gca().invert_yaxis()
    plt.show()

fig05.png

Après cela, collez-le simplement dans le papier avec savefig ('hoge.eps') et ainsi de suite.

Au fait, j'ai le sentiment que la signification de «dendrogramme (orientation = ...)» est différente entre paysage et portrait ... Scipy bug?

Recommended Posts

Heatmap avec dendrogramme en Python + matplotlib
Carte thermique par Python + matplotlib
Exploitez LibreOffice avec Python
Grattage avec chromedriver en python
Gérer les sons en Python
Grattage avec du sélénium en Python
Grattage avec Tor en Python
Combiné avec ordinal en Python
Créer une animation de tracé avec Python + Matplotlib
Manuel de graphisme Python avec Matplotlib.
Tester avec des nombres aléatoires en Python
GOTO en Python avec Sublime Text 3
Travailler avec LibreOffice en Python: import
Scraping avec Selenium en Python (Basic)
Numer0n avec des objets fabriqués avec Python
Ouvrez UTF-8 avec BOM en Python
Utiliser rospy avec virtualenv dans Python3
Utiliser Python mis en pyenv avec NeoVim
Lire des fichiers en parallèle avec Python
Générer un mot de passe pour le manuel avec python
Utiliser OpenCV avec Python 3 dans Window
Jusqu'à traiter de python dans Atom
Dessinez Riapnov Fractal avec Python, matplotlib
Quand matplotlib ne fonctionne pas avec python2.7
Effectuer un tracé de probabilité normale logarithmique avec Python, matplotlib
La première étape de Python Matplotlib
Démarrez avec Python avec Blender
Travailler avec des images DICOM en Python
Écrire de la documentation dans Sphinx avec Python Livereload
Afficher les formules de notation LaTeX en Python, matplotlib
Obtenez des données supplémentaires vers LDAP avec python
Livre en spirale en Python! Python avec un livre en spirale! (Chapitre 14 ~)
Essayez de vous connecter à qiita avec Python
[Python] Définissez la plage du graphique avec matplotlib
Python3> dans le mot clé> Vrai avec une correspondance partielle?
Contrôle exclusif avec fichier de verrouillage en Python
Affichage du graphique en chandeliers en Python (édition matplotlib)
Surveillance des appareils effectuée par Python On-box de IOS-XE
Essayez de travailler avec des données binaires en Python
Dessinez Nozomi Sasaki dans Excel avec python
Conseils pour gérer les binaires en Python
J'ai dessiné une carte thermique avec Seaborn [Python]
Afficher Python 3 dans le navigateur avec MAMP
Comment utiliser BigQuery en Python
Classe Trump en Python (avec comparaison)
Gérer les "années et mois" en Python
Traiter plusieurs listes avec for en Python
Remplacer non-ASCII par des expressions régulières en Python
[Python] Rendons matplotlib compatible avec le japonais
Un serveur Web de ligne (avec CGI) en python
Commençons avec TopCoder en Python (version 2020)
Traitez facilement des images en Python avec Pillow
Pour faire fonctionner la station d'horodatage en Python
Appelez APIGateWay avec APIKey dans les requêtes python
Lire des caractères dans des images avec Python OCR
Introduction de sip-4.14 dans l'environnement python3.2.2 avec MacOS 10.7.4
Pourquoi ne puis-je pas installer matplotlib avec python! !!