Reordering matrix elements to reflect column and row clustering in naiive python Reordering matrix elements to reflect column and row clustering in naiive python numpy numpy

Reordering matrix elements to reflect column and row clustering in naiive python


See my recent answer, copied in part below, to this related question.

import scipyimport pylabimport scipy.cluster.hierarchy as sch# Generate 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])# Compute and plot dendrogram.fig = pylab.figure()axdendro = fig.add_axes([0.09,0.1,0.2,0.8])Y = sch.linkage(D, method='centroid')Z = sch.dendrogram(Y, orientation='right')axdendro.set_xticks([])axdendro.set_yticks([])# Plot distance matrix.axmatrix = fig.add_axes([0.3,0.1,0.6,0.8])index = Z['leaves']D = D[index,:]D = D[:,index]im = axmatrix.matshow(D, aspect='auto', origin='lower')axmatrix.set_xticks([])axmatrix.set_yticks([])# Plot colorbar.axcolor = fig.add_axes([0.91,0.1,0.02,0.8])pylab.colorbar(im, cax=axcolor)# Display and save figure.fig.show()fig.savefig('dendrogram.png')

Dendrogram and distance matrix
(source: stevetjoa.com)


I'm not sure completely understand, but it appears you are trying to re-index each axis of the array based on sorts of the dendrogram indicies. I guess that assumes there is some comparative logic in each branch delineation. If this is the case then would this work(?):

>>> x_idxs = [(0,1,0,0),(0,1,1,1),(0,1,1),(0,0,1),(1,1,1,1),(0,0,0,0)]>>> y_idxs = [(1,1),(0,1),(1,0),(0,0)]>>> a = np.random.random((len(x_idxs),len(y_idxs)))>>> x_idxs2, xi = zip(*sorted(zip(x_idxs,range(len(x_idxs)))))>>> y_idxs2, yi = zip(*sorted(zip(y_idxs,range(len(y_idxs)))))>>> a2 = a[xi,:][:,yi]

x_idxs and y_idxs are the dendrogram indicies. a is the unsorted matrix. xi and yi are your new row/column array indicies. a2 is the sorted matrix while x_idxs2 and y_idxs2 are the new, sorted dendrogram indicies. This assumes that when the dendrogram was created that a 0 branch column/row is always comparatively larger/smaller than a 1 branch.

If your y_idxs and x_idxs are not lists but are numpy arrays, then you could use np.argsort in a similar manner.


I know this is very late to the game, but I made a plotting object based on the code from the post on this page. It's registered on pip, so to install you just have to call

pip install pydendroheatmap

check out the project's github page here : https://github.com/themantalope/pydendroheatmap