Reputation: 7490
I have written two functions. The first function takes in a distance matrix of point vectors and does Mult-Dimensional Scaling of the point to 3D and returns a matrix (pos)with points transformed to 3 dimensional space such that the spacing is reduced in the same proportion. In the first function you will also see I have pickled my 'pos' matrix to disk.
The second function is a plotting function which takes that pos matrix as input and plots the points .
def MDS(dist):
""" This function is going to get the Multi-dimensional scaling"""
# Visualising distance using MDS
from sklearn.manifold import MDS
# two components as we're plotting points in a two-dimensional plane
# "precomputed" because we provide a distance matrix
# we will also specify `random_state` so the plot is reproducible.
mds = MDS(n_components=3, dissimilarity="precomputed", random_state=1)
pos = mds.fit_transform(dist)
# Pickling the MDS estimator
outfile=open("MDS_"+z[c]+".p",'wb')
cPickle.dump(mds,outfile)
outfile.close()
outfile=open("MDS_pos"+z[c]+".p",'wb')
cPickle.dump(pos,outfile)
outfile.close()
return pos
# Visualising the plot
def plotMds(pos,outcome):
"""Plotting the MDS output"""
header=list(outcome)
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.patches as mpatches
fig = plt.figure(figsize=(25,20))
ax = fig.add_subplot(111, projection='3d')
red_patch = mpatches.Patch(color='red', label='Terminated')
green_patch = mpatches.Patch(color='green', label='Completed Positive')
blue_patch=mpatches.Patch(color='blue', label='Completed Negative')
plt.legend(handles=[red_patch,green_patch,blue_patch])
plt.title('MDS by'+z[c])
for x, y, w, name in zip(pos[:, 0], pos[:,1], pos[:, 2], header):
if(name=='Completed Negative'):
color='blue'
elif(name=='Completed Positive'):
color='green'
else:
color='red'
ax.scatter(x, y, w,s=55,c=color)
fig.savefig('mds_'+z[c]+'.png')
I get the following output as the saved .png file.
This image is giving weird output as I have 5000 points to plot. And all it gives is just one point.
But if I take the same plotting code written above and unpickle the pos matrix which I pickled in the first function and plot it separately outside a function definition, I get a correct plot.
infile=open("MDS_posI.p",'rb')
check=pickle.load(infile)
infile.close()
infile=open("outcomeI.p",'rb')
outcome=pickle.load(infile)
infile.close()
header=list(outcome)
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.patches as mpatches
fig = plt.figure(figsize=(25,20))
ax = fig.add_subplot(111, projection='3d')
red_patch = mpatches.Patch(color='red', label='Terminated')
green_patch = mpatches.Patch(color='green', label='Completed Positive')
blue_patch=mpatches.Patch(color='blue', label='Completed Negative')
plt.legend(handles=[red_patch,green_patch,blue_patch])
for x, y, z, name in zip(check[:, 0], check[:, 1], check[:, 2], header):
if(name=='Completed Negative'):
color='blue'
elif(name=='Completed Positive'):
color='green'
else:
color='red'
ax.scatter(x, y, z,s=65,c=color)
If you see all I am doing here is taking the same plotting code from above and unpickling the pos matrix which I created in the first function and plotting it. Just that this time the plotting code is not inside a function definition. Here is the output.
This plot does makes sense as I do have 5000 points to plot.
Can someone help me understand what is going wrong here that the first code is just saving the plot with one point?
Upvotes: 0
Views: 532
Reputation: 152637
You should put the ax.scatter(...)
inside the for
loop, otherwise it will only plot the last point of the loop.
Upvotes: 1