How to plot vectors in python using matplotlib

后端 未结 6 553
太阳男子
太阳男子 2020-12-24 03:30

I am taking a course on linear algebra and I want to visualize the vectors in action, such as vector addition, normal vector, so on.

For instance:

         


        
相关标签:
6条回答
  • 2020-12-24 03:37

    How about something like

    import numpy as np
    import matplotlib.pyplot as plt
    
    V = np.array([[1,1], [-2,2], [4,-7]])
    origin = np.array([[0, 0, 0],[0, 0, 0]]) # origin point
    
    plt.quiver(*origin, V[:,0], V[:,1], color=['r','b','g'], scale=21)
    plt.show()
    

    Then to add up any two vectors and plot them to the same figure, do so before you call plt.show(). Something like:

    plt.quiver(*origin, V[:,0], V[:,1], color=['r','b','g'], scale=21)
    v12 = V[0] + V[1] # adding up the 1st (red) and 2nd (blue) vectors
    plt.quiver(*origin, v12[0], v12[1])
    plt.show()
    

    NOTE: in Python2 use origin[0], origin[1] instead of *origin

    0 讨论(0)
  • 2020-12-24 03:37

    All nice solutions, borrowing and improvising for special case -> If you want to add a label near the arrowhead:

    
        arr = [2,3]
        txt = “Vector X”
        ax.annotate(txt, arr)
        ax.arrow(0, 0, *arr, head_width=0.05, head_length=0.1)
    
    
    0 讨论(0)
  • 2020-12-24 03:39

    Thanks to everyone, each of your posts helped me a lot. rbierman code was pretty straight for my question, I have modified a bit and created a function to plot vectors from given arrays. I'd love to see any suggestions to improve it further.

    import numpy as np
    import matplotlib.pyplot as plt
    def plotv(M):
        rows,cols = M.T.shape
        print(rows,cols)
    
        #Get absolute maxes for axis ranges to center origin
        #This is optional
        maxes = 1.1*np.amax(abs(M), axis = 0)
        colors = ['b','r','k']
        fig = plt.figure()
        fig.suptitle('Vectors', fontsize=10, fontweight='bold')
    
        ax = fig.add_subplot(111)
        fig.subplots_adjust(top=0.85)
        ax.set_title('Vector operations')
    
        ax.set_xlabel('x')
        ax.set_ylabel('y')
    
        for i,l in enumerate(range(0,cols)):
            # print(i)
            plt.axes().arrow(0,0,M[i,0],M[i,1],head_width=0.2,head_length=0.1,zorder=3)
    
            ax.text(M[i,0],M[i,1], str(M[i]), style='italic',
                bbox={'facecolor':'red', 'alpha':0.5, 'pad':0.5})
    
        plt.plot(0,0,'ok') #<-- plot a black point at the origin
        # plt.axis('equal')  #<-- set the axes to the same scale
        plt.xlim([-maxes[0],maxes[0]]) #<-- set the x axis limits
        plt.ylim([-maxes[1],maxes[1]]) #<-- set the y axis limits
    
        plt.grid(b=True, which='major') #<-- plot grid lines
        plt.show()
    
    r = np.random.randint(4,size=[2,2])
    print(r[0,:])
    print(r[1,:])
    r12 = np.add(r[0,:],r[1,:])
    print(r12)
    plotv(np.vstack((r,r12)))
    

    Vector addition performed on random vectors

    0 讨论(0)
  • 2020-12-24 03:47

    Your main problem is you create new figures in your loop, so each vector gets drawn on a different figure. Here's what I came up with, let me know if it's still not what you expect:

    CODE:

    import numpy as np
    import matplotlib.pyplot as plt
    M = np.array([[1,1],[-2,2],[4,-7]])
    
    rows,cols = M.T.shape
    
    #Get absolute maxes for axis ranges to center origin
    #This is optional
    maxes = 1.1*np.amax(abs(M), axis = 0)
    
    for i,l in enumerate(range(0,cols)):
        xs = [0,M[i,0]]
        ys = [0,M[i,1]]
        plt.plot(xs,ys)
    
    plt.plot(0,0,'ok') #<-- plot a black point at the origin
    plt.axis('equal')  #<-- set the axes to the same scale
    plt.xlim([-maxes[0],maxes[0]]) #<-- set the x axis limits
    plt.ylim([-maxes[1],maxes[1]]) #<-- set the y axis limits
    plt.legend(['V'+str(i+1) for i in range(cols)]) #<-- give a legend
    plt.grid(b=True, which='major') #<-- plot grid lines
    plt.show()
    

    OUTPUT:

    EDIT CODE:

    import numpy as np
    import matplotlib.pyplot as plt
    M = np.array([[1,1],[-2,2],[4,-7]])
    
    rows,cols = M.T.shape
    
    #Get absolute maxes for axis ranges to center origin
    #This is optional
    maxes = 1.1*np.amax(abs(M), axis = 0)
    colors = ['b','r','k']
    
    
    for i,l in enumerate(range(0,cols)):
        plt.axes().arrow(0,0,M[i,0],M[i,1],head_width=0.05,head_length=0.1,color = colors[i])
    
    plt.plot(0,0,'ok') #<-- plot a black point at the origin
    plt.axis('equal')  #<-- set the axes to the same scale
    plt.xlim([-maxes[0],maxes[0]]) #<-- set the x axis limits
    plt.ylim([-maxes[1],maxes[1]]) #<-- set the y axis limits
    plt.grid(b=True, which='major') #<-- plot grid lines
    plt.show()
    

    EDIT OUTPUT:

    0 讨论(0)
  • 2020-12-24 03:47

    What did you expect the following to do?

    v1 = [0,0],[M[i,0],M[i,1]]
    v1 = [M[i,0]],[M[i,1]]
    

    This is making two different tuples, and you overwrite what you did the first time... Anyway, matplotlib does not understand what a "vector" is in the sense you are using. You have to be explicit, and plot "arrows":

    In [5]: ax = plt.axes()
    
    In [6]: ax.arrow(0, 0, *v1, head_width=0.05, head_length=0.1)
    Out[6]: <matplotlib.patches.FancyArrow at 0x114fc8358>
    
    In [7]: ax.arrow(0, 0, *v2, head_width=0.05, head_length=0.1)
    Out[7]: <matplotlib.patches.FancyArrow at 0x115bb1470>
    
    In [8]: plt.ylim(-5,5)
    Out[8]: (-5, 5)
    
    In [9]: plt.xlim(-5,5)
    Out[9]: (-5, 5)
    
    In [10]: plt.show()
    

    Result:

    0 讨论(0)
  • 2020-12-24 03:50

    This may also be achieved using matplotlib.pyplot.quiver, as noted in the linked answer;

    plt.quiver([0, 0, 0], [0, 0, 0], [1, -2, 4], [1, 2, -7], angles='xy', scale_units='xy', scale=1)
    plt.xlim(-10, 10)
    plt.ylim(-10, 10)
    plt.show()
    

    0 讨论(0)
提交回复
热议问题