Home > OS >  How to plot R's vegan::procrustes using Python (SciPy, NumPy, and Matplotlib)?
How to plot R's vegan::procrustes using Python (SciPy, NumPy, and Matplotlib)?

Time:01-29

I'm following the vegan tutorial on procrustes analysis:

enter image description here

Now with Python I can choose either:

  • enter image description here

    CodePudding user response:

    The manner in which the vegan package runs through monoMDS doesn't seem to align with any of the methods that Python uses. The code in vegan is all based on Fortran. You could link the Fortan to Python, just like you can in R.

    While the scaling is different, the rotation matrix within vare.proc is exactly the same as the rotation matrix (array?) in the Python coded object above vare_proc. I found that to be interesting.

    If I bring in the pieces of the content in R for your object vare.proc, I can make the exact graph.

    First, I used R Markdown to share objects between Python and R.

    # compare to R
    # vpR = vareProc$rotation
    vpR_py = r.vpR    
    # vpYrot = vareProc$Yrot
    vpYrot_py = r.vpYrot
    # vpX = vareProc$X
    vpX_py = r.vpX
    

    Then I used these objects to make the replica

    # build the plot exactly like vegan 
    # using https://github.com/vegandevs/vegan/blob/master/R/plot.procrustes.R
    tails = vpYrot_py
    heads = vpX_py
    
    # find the ranges
    xMax = max(abs(np.hstack((tails[:,0], heads[:,0]))))
    yMax = max(abs(np.hstack((tails[:,1], heads[:,1]))))
    
    plt.figure(dpi = 100) 
    fig, ax = plt.subplots()
    ax.set_aspect('equal')
    ax.set_xlim(-xMax, xMax)
    ax.set_ylim(-yMax, yMax)
    
    # add points
    ax.scatter(x = tails[:,0],
               y = tails[:,1],
               facecolors = 'none',
               edgecolors = 'k')
    
    # add origin axes
    ax.axhline(y = 0, color='k', ls = '--', linewidth = 1) # using dashed for origin
    ax.axvline(x = 0, color='k', ls = '--', linewidth = 1)
    
    # add rotation axes
    ax.axline(xy1 = (0, 0), color = 'k',
              slope = vpR_py[0, 1]/vpR_py[0, 0])
    ax.axline(xy1 = (0, 0), color = 'k',
              slope = vpR_py[1, 1]/vpR_py[1, 0])
    
    # add arrows
    for i in range(0, len(tails)):
      ax.annotate("", xy = heads[i,:],
                  xycoords = 'data',
                  xytext = tails[i,:], 
                  arrowprops=dict(arrowstyle="->",
                                  color = 'blue'))
    
    plt.tight_layout(pad = 2)
    plt.show()
    

    From matplotlib

    enter image description here

    From vegan

    enter image description here

  •  Tags:  
  • Related