# How to plot data output of clustering?

I tried clustering a set of data (a set of marks) and got 2 clusters. I would like to graphically represent it. Bit confused about the representation, since I don't have the (x,y) coordinates.

Also looking for MATLAB/Python function for doing so.

EDIT

I think posting data make the question clearer. I have two clusters I made using kmeans clustering in Python (not using scipy). They are

class 1: a=[3222403552.0, 3222493472.0, 3222491808.0, 3222489152.0, 3222413632.0,
3222394528.0, 3222414976.0, 3222522768.0, 3222403552.0, 3222498896.0, 3222541408.0,
3222403552.0, 3222402816.0, 3222588192.0, 3222403552.0, 3222410272.0, 3222394560.0,
3222402704.0, 3222298192.0, 3222409264.0, 3222414688.0, 3222522512.0, 3222404096.0,
3222486720.0, 3222403968.0, 3222486368.0, 3222376320.0, 3222522896.0, 3222403552.0,
3222374480.0, 3222491648.0, 3222543024.0, 3222376848.0, 3222403552.0, 3222591616.0,
3222376944.0, 3222325568.0, 3222488864.0, 3222548416.0, 3222424176.0, 3222415024.0,
3222403552.0, 3222407504.0, 3222489584.0, 3222407872.0, 3222402736.0, 3222402032.0,
3222410208.0, 3222414816.0, 3222523024.0, 3222552656.0, 3222487168.0, 3222403728.0,
3222319440.0, 3222375840.0, 3222325136.0, 3222311568.0, 3222491984.0, 3222542032.0,
3222539984.0, 3222522256.0, 3222588336.0, 3222316784.0, 3222488304.0, 3222351360.0,
3222545536.0, 3222323728.0, 3222413824.0, 3222415120.0, 3222403552.0, 3222514624.0,
3222408000.0, 3222413856.0, 3222408640.0, 3222377072.0, 3222324304.0, 3222524016.0,
3222324000.0, 3222489808.0, 3222403552.0, 3223571920.0, 3222522384.0, 3222319712.0,
3222374512.0, 3222375456.0, 3222489968.0, 3222492752.0, 3222413920.0, 3222394448.0,
3222403552.0, 3222403552.0, 3222540576.0, 3222407408.0, 3222415072.0, 3222388272.0,
3222549264.0, 3222325280.0, 3222548208.0, 3222298608.0, 3222413760.0, 3222409408.0,
3222542528.0, 3222473296.0, 3222428384.0, 3222413696.0, 3222486224.0, 3222361280.0,
3222522640.0, 3222492080.0, 3222472144.0, 3222376560.0, 3222378736.0, 3222364544.0,
3222407776.0, 3222359872.0, 3222492928.0, 3222440496.0, 3222499408.0, 3222450272.0,
3222351904.0, 3222352480.0, 3222413952.0, 3222556416.0, 3222410304.0, 3222399984.0,
3222494736.0, 3222388288.0, 3222403552.0, 3222323824.0, 3222523616.0, 3222394656.0,
3222404672.0, 3222405984.0, 3222490432.0, 3222407296.0, 3222394720.0, 3222596624.0,
3222597520.0, 3222598048.0, 3222403552.0, 3222403552.0, 3222403552.0, 3222324448.0,
3222408976.0, 3222448160.0, 3222366320.0, 3222489344.0, 3222403552.0, 3222494480.0,
3222382032.0, 3222450432.0, 3222352000.0, 3222352528.0, 3222414032.0, 3222728448.0,
3222299456.0, 3222400016.0, 3222495056.0, 3222388848.0, 3222403552.0, 3222487568.0,
3222523744.0, 3222394624.0, 3222408112.0, 3222406496.0, 3222405616.0, 3222592160.0,
3222549360.0, 3222438560.0, 3222597024.0, 3222597616.0, 3222598128.0, 3222403552.0,
3222403552.0, 3222403552.0, 3222499056.0, 3222408512.0, 3222402064.0, 3222368992.0,
3222511376.0, 3222414624.0, 3222554816.0, 3222494608.0, 3222449792.0, 3222351952.0,
3222352272.0, 3222394736.0, 3222311856.0, 3222414288.0, 3222402448.0, 3222401056.0,
3222413568.0, 3222298848.0, 3222297184.0, 3222488000.0, 3222490528.0, 3222394688.0,
3222408224.0, 3222406672.0, 3222404896.0, 3222443120.0, 3222403552.0, 3222596400.0,
3222597120.0, 3222597712.0, 3222400896.0, 3222403552.0, 3222403552.0, 3222403552.0,
3222299200.0, 3222321296.0, 3222364176.0, 3222602208.0, 3222513040.0, 3222414656.0,
3222564864.0, 3222407904.0, 3222449984.0, 3222352096.0, 3222352432.0, 3222452832.0,
3222368560.0, 3222414368.0, 3222399376.0, 3222298352.0, 3222573152.0, 3222438080.0,
3222409168.0, 3222523488.0, 3222394592.0, 3222405136.0, 3222490624.0, 3222406928.0,
3222407104.0, 3222442464.0, 3222403552.0, 3222596512.0, 3222597216.0, 3222597968.0,
3222438208.0, 3222403552.0, 3222403552.0, 3222403552.0]

class 2: b=[3498543128.0, 3498542920.0, 3498543252.0, 3498543752.0, 3498544872.0,
3498544528.0, 3498543024.0, 3498542548.0, 3498542232.0]


I would like to plot it. I tried the following and got the following result when I plot a and b.

pylab.plot(a,'x')
pylab.plot(b,'o')
pylab.show()


can I get a better visualization of clustering?

-
That really depends on you've done the clustering :) If you show a little example of the data you have i'm sure you'll get an answer – david w Apr 22 '11 at 10:40
Using different colors and markers tends to be the simplest/easiest to read. If all you have is 2 clusters, then you can just print 0/1 or O/X for the different values. – Marcin Apr 22 '11 at 13:15
Please tell what you mean by "a set of marks." How many variables do you have with which to characterize the clusters? Also, are you confident that 2 is the best number of clusters to use? Many times one has to use cluster analysis programs iteratively; at the outset one might get just 2, but with some adjustments one might get a more interesting and informative higher number. – rolando2 Apr 23 '11 at 15:53
I used kmeans where I have to give the number of clusters explicitely – user2721 Apr 28 '11 at 2:06

Usually you'd plot the original values in a scatterplot (or a matrix of scatterplots if you have many of them) and use colour to show your groups.

You asked for an answer in python, and you actually do all the clustering and plotting with scipy, numpy and matplotlib:

## Start by making some data

import numpy as np
from scipy import cluster
from matplotlib import pyplot

np.random.seed(123)
tests = np.reshape( np.random.uniform(0,100,60), (30,2) )
#tests[1:4]
#array([[ 22.68514536,  55.13147691],
#       [ 71.94689698,  42.31064601],
#       [ 98.07641984,  68.48297386]])


## How many clusters?

This is the hard thing about k-means, and there are lots of methods. Let's use the elbow method

#plot variance for each value for 'k' between 1,10
initial = [cluster.vq.kmeans(tests,i) for i in range(1,10)]
pyplot.plot([var for (cent,var) in initial])
pyplot.show()


## Assign your observations to classes, and plot them

I reckon index 3 (i.e. 4 clusters) is as good as any so

cent, var = initial[3]
#use vq() to get as assignment for each obs.
assignment,cdist = cluster.vq.vq(tests,cent)
pyplot.scatter(tests[:,0], tests[:,1], c=assignment)
pyplot.show()


Just work out where you can stick whatever you've already done into that workdflow (and I hope you clusters are a bit nicer than the random ones!)

-
Your answer looks great. Can I use it efficiently for my data. Couldnt get time to try it. – user2721 Apr 28 '11 at 7:15
@david w: This is one of the best answers I have seen! Thank you very much for posting a standalone example. At least, I understand the crux of your answer :) Thank you once again! – Legend Jul 10 '11 at 5:26
@david w: The only question I had is the elbow method shows increasing values and your plot shows decreasing. Is this because you are using the distortion values directly from kmeans? How can I convert this to look like the Wikipedia's elbow plot? And as a last question, would you happen to know how to do this for kmeans2 instead of kmeans? – Legend Jul 10 '11 at 5:36

Perhaps try something like Fastmap to plot your set of marks using their relative distances.

(still) nothing clever has written up Fastmap in python to plot strings and could be easily updated to handle lists of attributes if you wrote up your own distance metric.

Below is a standard euclidean distance I use that takes two lists of attributes as parameters. If your lists have a class value, don't use it in the distance calculation.

def distance(vecone, vectwo, d=0.0):
for i in range(len(vecone)):
if isnumeric(vecone[i]):
d = d + (vecone[i] - vectwo[i])**2
elif vecone[i] is not vectwo[i]:
d += 1.0
return math.sqrt(d)

def isnumeric(s):
try:
float(s)
return True
except ValueError:
return False

-

I'm not a python expert, but it is extremely helpful to plot the 1st 2 principal components against each other on the x,y axes.

Not sure which packages you are using, but here is a sample link:

http://pyrorobotics.org/?page=PyroModuleAnalysis

-
I am not a statistics expert. Could you please explain more about the plotting idea? – user2721 Apr 29 '11 at 2:16
The basic idea is that many variables are correlated with each other and everything can be reduced to only two variables which are uncorrelated with each other and explain "most" of the variation in the data. You need to read up on principal components analysis and apply a package which allows you to implement it. en.wikipedia.org/wiki/Principal_component_analysis – Ralph Winters Apr 29 '11 at 14:32