Baktaawar
Baktaawar

Reputation: 7490

Matplotlib 3D graph giving different plot when used inside a function

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.

enter image description here 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.

enter image description here

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

Answers (1)

MSeifert
MSeifert

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

Related Questions