Ordered colored plot after clustering using python

浪子不回头ぞ 提交于 2020-01-05 18:26:40

问题


I have a 1D array called data=[5 1 100 102 3 4 999 1001 5 1 2 150 180 175 898 1012]. I am using python scipy.cluster.vq to find clusters within it. There are 3 clusters in the data. After clustering when I'm trying to plot the data, there is no order in it.

It would be great if it's possible to plot the data in the same order as it is given and color different sections belong to different groups or clusters.

Here is my code:

import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.vq import kmeans, vq


data = np.loadtxt('rawdata.csv', delimiter=' ')
#----------------------kmeans------------------
centroid,_ = kmeans(data, 3) 
idx,_ = vq(data, centroid)
x=np.linspace(0,(len(data)-1),len(data))

fig = plt.figure(1)
plt.plot(x,data)
plot1=plt.plot(data[idx==0],'ob')
plot2=plt.plot(data[idx==1],'or')
plot3=plt.plot(data[idx==2],'og')
plt.show()

Here is my plot http://s29.postimg.org/9gf7noe93/figure_1.png (The blue graph in the background is in-order, after clustering,it messed up)

Thanks!

Update :

I wrote the following code to implement in-order colored plot after clustering,

import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.vq import kmeans, vq

data = np.loadtxt('rawdata.csv', delimiter=' ')
#----------------------kmeans-----------------------------
centroid,_ = kmeans(data, 3)  # three clusters
idx,_ = vq(data, centroid)
x=np.linspace(0,(len(data)-1),len(data))
fig = plt.figure(1)
plt.plot(x,data)

for i in range(0,(len(data)-1)):
    if data[i] in data[idx==0]:
       plt.plot(x[i],(data[i]),'ob' )
    if data[i] in data[idx==1]:
       plt.plot(x[i],(data[i]),'or' )
    if data[i] in data[idx==2]:
       plt.plot(x[i],(data[i]),'og' )
 plt.show()

The problem with the above code is it's too slow. And my array size is over 3million. So this code will take forever to finish it's job for me. I really appreciate if someone can provide vectorized version of the above mentioned code. Thanks!


回答1:


You can plot the clustered data points based on their distances from the cluster center and then write the index of each data point close to that in order to see how they scattered based on their clustering properties:

import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.vq import kmeans, vq
from scipy.spatial.distance import cdist
data=np.array([   5,    1,  100,  102,    3,    4,  999, 1001,    5,    1,    2,    150,  180,  175,  898, 1012])
centroid,_ = kmeans(data, 3) 
idx,_ = vq(data, centroid)
X=data.reshape(len(data),1)
Y=centroid.reshape(len(centroid),1)
D_k = cdist( X, Y, metric='euclidean' )
colors = ['red', 'green', 'blue']
pId=range(0,(len(data)-1))
cIdx = [np.argmin(D) for D in D_k]
dist = [np.min(D) for D in D_k]
r=np.vstack((data,dist)).T
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
mark=['^','o','>']
for i, ((x,y), kls) in enumerate(zip(r, cIdx)):
    ax.plot(r[i,0],r[i,1],color=colors[kls],marker=mark[kls])
    ax.annotate(str(i), xy=(x,y), xytext=(0.5,0.5), textcoords='offset points',
                 size=8,color=colors[kls])


ax.set_yscale('log')
ax.set_xscale('log')
ax.set_xlabel('Data')
ax.set_ylabel('Distance')
plt.show()

Update:

if you are very keen of using vectorize procedure you can do it as following for a randomly generated data:

data=np.random.uniform(1,1000,3000)
@np.vectorize
def plotting(i):
    ax.plot(i,data[i],color=colors[cIdx[i]],marker=mark[cIdx[i]])


mark=['>','o','^']
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plotting(range(len(data)))
ax.set_xlabel('index')
ax.set_ylabel('Data')
plt.show()



来源:https://stackoverflow.com/questions/25344895/ordered-colored-plot-after-clustering-using-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!