【问题标题】:How to plot vectors in python using matplotlib如何使用matplotlib在python中绘制向量
【发布时间】:2017-07-06 00:53:54
【问题描述】:

我正在学习线性代数的课程,我想可视化正在运行的向量,例如向量加法、法线向量等。

例如:

V = np.array([[1,1],[-2,2],[4,-7]])

在这种情况下,我想绘制 3 个向量 V1 = (1,1), M2 = (-2,2), M3 = (4,-7)

然后我应该能够添加 V1,V2 来绘制一个新的向量 V12(全部在一个图中)。

当我使用以下代码时,情节与预期不符

import numpy as np
import matplotlib.pyplot as plt
M = np.array([[1,1],[-2,2],[4,-7]])

print("vector:1")
print(M[0,:])
# print("vector:2")
# print(M[1,:])
rows,cols = M.T.shape
print(cols)

for i,l in enumerate(range(0,cols)):
    print("Iteration: {}-{}".format(i,l))
    print("vector:{}".format(i))
    print(M[i,:])
    v1 = [0,0],[M[i,0],M[i,1]]
    # v1 = [M[i,0]],[M[i,1]]
    print(v1)
    plt.figure(i)
    plt.plot(v1)
    plt.show()

【问题讨论】:

标签: python python-2.7 numpy matplotlib vector


【解决方案1】:

一旦你弄清楚它令人讨厌的细微差别,Quiver 是一个很好的方法,比如不以原始比例绘制向量。据我所知,您必须将这些参数传递给 quiver 调用,正如许多人指出的那样:angles='xy', scale_units='xy', scale=1 AND 您应该设置您的 plt.xlimplt.ylim 以便获得一个正方形或接近方形网格。这是我让它始终按照我想要的方式绘制的唯一方法。例如,将原点作为 *[0,0] 并将 U, V 作为 *[5,3] 表示生成的图应该是一个以 0,0 原点为中心的向量,在 x 轴右侧超过 5 个单位和 3 个单位在 y 轴上。

【讨论】:

    【解决方案2】:

    为了使矢量长度和角度与绘图的 x,y 坐标相匹配,您可以使用 plt.quiver 的以下选项:

    plt.figure(figsize=(5,2), dpi=100)
    plt.quiver(0,0,250,100, angles='xy', scale_units='xy', scale=1)
    plt.xlim(0,250)
    plt.ylim(0,100)
    

    【讨论】:

      【解决方案3】:

      怎么样

      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()
      

      然后将任意两个向量相加并将它们绘制成同一个图形,在调用 plt.show() 之前执行此操作。比如:

      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()
      

      注意:在 Python2 中使用 origin[0], origin[1] 而不是 *origin

      【讨论】:

      • +1 很酷,你知道是否可以为箭袋中的每个箭头创建一个图例条目吗?
      • 不幸的是,没有线索 :/ 我不太肯定有办法为每个人添加单独的图例。也许像figtexttext 这样的东西可以做!?
      • 绝对可以通过将以下内容添加到代码 sn-p 中来为每个向量条目添加图例。 plt.quiver(*origin, V[:,0], V[:,1], color=['r','b','g'], scale=21, label="Name of vector") 在剧情末尾添加 plt.legend()
      • 在 Python3.5+ 中,星号解包列表stackoverflow.com/a/3480190/2839786
      • 如果坐标轴与矢量幅度匹配会非常有帮助。有没有办法做到这一点?
      【解决方案4】:

      所有不错的解决方案,特殊情况的借用和即兴创作 -> 如果你想在箭头附近添加标签:

      
          arr = [2,3]
          txt = “Vector X”
          ax.annotate(txt, arr)
          ax.arrow(0, 0, *arr, head_width=0.05, head_length=0.1)
      
      

      【讨论】:

        【解决方案5】:

        感谢大家,您的每一篇文章都对我有很大帮助。 rbierman 代码对我的问题非常直接,我进行了一些修改并创建了一个函数来绘制来自给定数组的向量。我很乐意看到任何进一步改进它的建议。

        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

        【讨论】:

          【解决方案6】:

          您希望以下内容做什么?

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

          这是在创建两个不同的元组,你会覆盖你第一次做的......无论如何,matplotlib 不理解你正在使用的意义上的“向量”是什么。您必须明确,并绘制“箭头”:

          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()
          

          结果:

          【讨论】:

          • 谢谢,我已经修改了v1的额外行。
          • 我在测试所有的可能性,最后决定向社区询问,但这样做我并没有删除该行。我想要的只是在我们在笔记本中绘制时绘制一个矢量。
          【解决方案7】:

          这也可以使用matplotlib.pyplot.quiver 来实现,如链接答案中所述;

          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()
          

          【讨论】:

            【解决方案8】:

            您的主要问题是您在循环中创建了新图形,因此每个向量都绘制在不同的图形上。这是我想出的,如果它仍然不是你所期望的,请告诉我:

            代码:

            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()
            

            输出:

            编辑代码:

            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()
            

            编辑输出:

            【讨论】:

            • 看起来很酷,我们可以为每个向量设置箭头吗?
            • 是的!我个人认为原点处的点足以提供方向性,但你可以从 juanpa 在他的回答中窃取一些命令。我尝试使用箭头,但很难让它们成为图例中的不同条目并适合屏幕(请参阅更新)
            • 嘿,谢谢,我已经注释掉了 plt.axis('equal')。现在它显示了所有具有指定 x,y 限制的向量。
            • 也许有一点更新:对我来说,使用 Matplotlib 3.4.1,您编辑的答案应该在绘制箭头时省略 .axes(),例如。 plt.arrow(0,0,M[i,0],M[i,1],head_width=0.3,head_length=0.3,color = colors[i], length_includes_head=True)
            猜你喜欢
            • 2023-03-06
            • 1970-01-01
            • 2021-02-02
            • 2021-12-30
            • 2015-01-17
            • 1970-01-01
            • 2018-05-18
            • 2012-08-29
            • 1970-01-01
            相关资源
            最近更新 更多