graphique des résultats du regroupement hiérarchique ontop d'une matrice de données en python

Comment puis-je tracer un dendrogramme juste au-dessus d'une matrice de valeurs, réordonnée de façon appropriée pour refléter le regroupement, en Python? Un exemple est le chiffre suivant:

https://publishing-cdn.elifesciences.org/07103/elife-07103-fig6-figsupp1-v2.jpg

j'utilise scipy.cluster.dendrogramme pour faire mon dendrogramme et effectuer le regroupement hiérarchique sur une matrice de données. Comment puis-je tracer les données comme une matrice où les rangées ont été réorganisées pour refléter un regroupement induit par la Coupe du dendrogramme à un seuil particulier, et le dendrogramme a-t-il été tracé le long de la matrice? Je sais comment tracer le dendrogramme en scipy, mais pas comment tracer la matrice d'intensité des données avec la barre d'échelle droite à côté.

Toute aide serait grandement appréciée.

46
demandé sur Martin Broadhurst 2010-06-06 06:50:24

2 réponses

La question n'est pas de définir matrice très bien: "matrice de valeurs", "matrice de données". Je suppose que vous voulez dire un matrice de distance . En d'autres termes, l'élément D_ij dans le N-by-N symétrique matrice de distance D indique la distance entre deux vecteurs de caractéristique, x_i et x_j. Est-ce exact?

si oui, alors essayez ceci (révisé le 13 juin 2010, pour refléter deux différents dendrogrammes):

import scipy
import pylab
import scipy.cluster.hierarchy as sch
from scipy.spatial.distance import squareform


# Generate random features and distance matrix.
x = scipy.rand(40)
D = scipy.zeros([40,40])
for i in range(40):
    for j in range(40):
        D[i,j] = abs(x[i] - x[j])

condensedD = squareform(D)

# Compute and plot first dendrogram.
fig = pylab.figure(figsize=(8,8))
ax1 = fig.add_axes([0.09,0.1,0.2,0.6])
Y = sch.linkage(condensedD, method='centroid')
Z1 = sch.dendrogram(Y, orientation='left')
ax1.set_xticks([])
ax1.set_yticks([])

# Compute and plot second dendrogram.
ax2 = fig.add_axes([0.3,0.71,0.6,0.2])
Y = sch.linkage(condensedD, method='single')
Z2 = sch.dendrogram(Y)
ax2.set_xticks([])
ax2.set_yticks([])

# Plot distance matrix.
axmatrix = fig.add_axes([0.3,0.1,0.6,0.6])
idx1 = Z1['leaves']
idx2 = Z2['leaves']
D = D[idx1,:]
D = D[:,idx2]
im = axmatrix.matshow(D, aspect='auto', origin='lower', cmap=pylab.cm.YlGnBu)
axmatrix.set_xticks([])
axmatrix.set_yticks([])

# Plot colorbar.
axcolor = fig.add_axes([0.91,0.1,0.02,0.6])
pylab.colorbar(im, cax=axcolor)
fig.show()
fig.savefig('dendrogram.png')

Plot

bonne chance! Laissez-moi savoir si vous avez besoin de plus d'aide.


Modifier: pour différentes couleurs, ajuster l'attribut cmap dans imshow . Voir le scipy/matplotlib docs pour des exemples. Cette page décrit également comment créer votre propre colormap. Pour plus de commodité, je recommande d'utiliser un préexistante de la palette de couleurs. Dans mon exemple, j'ai utilisé YlGnBu .


Edit: add_axes ( voir la documentation ici ) accepte une liste ou un tuple: (left, bottom, width, height) . Par exemple, (0.5,0,0.5,1) , ajoute un Axes sur la moitié droite de la figure. (0,0.5,1,0.5) , ajoute un Axes sur la moitié supérieure de la figure.

la plupart des gens utilisent probablement add_subplot pour sa commodité. J'aime add_axes pour son contrôle.

pour enlever la bordure, utilisez add_axes([left,bottom,width,height], frame_on=False) . Voir exemple ici.

87
répondu Steve Tjoa 2018-09-26 13:50:48

si en plus de la matrice et du dendrogramme il est nécessaire d'afficher les étiquettes des éléments, le code suivant peut être utilisé, qui affiche toutes les étiquettes tournant les étiquettes x et changeant la taille de la police pour éviter le chevauchement sur l'axe des X. Il faut déplacer la barre de couleur pour avoir de l'espace pour les étiquettes y:

axmatrix.set_xticks(range(40))
axmatrix.set_xticklabels(idx1, minor=False)
axmatrix.xaxis.set_label_position('bottom')
axmatrix.xaxis.tick_bottom()

pylab.xticks(rotation=-90, fontsize=8)

axmatrix.set_yticks(range(40))
axmatrix.set_yticklabels(idx2, minor=False)
axmatrix.yaxis.set_label_position('right')
axmatrix.yaxis.tick_right()

axcolor = fig.add_axes([0.94,0.1,0.02,0.6])

le résultat obtenu est le suivant (avec une carte de couleur différente):

The result obtained is this:

8
répondu Picarus 2014-04-13 17:48:06