首页 > 编程问答 >Python Matplotlib Quiver 绘制向量场

Python Matplotlib Quiver 绘制向量场

时间:2024-08-04 17:12:34浏览次数:18  
标签:python matplotlib vector gravity

我正在尝试使用 Matplotlib 的 quiver 函数绘制引力矢量场,我有一个函数可以计算由任意数量的质量引起的引力场,但是在绘制它时,我在质量位置周围得到了奇怪的结果。出于矢量绘图的目的,该函数返回 x 和 y 方向上的场分量、它们的 x 和 y 坐标以及 2D 场数组,这对于绘图不是必需的,但对于稍后与此无关的其他代码来说是必需的。 x 和 y 分量是列表,其中每个索引的 4 个列表中的每个值对应于相同的元素,因此在所有 4 个列表中的索引 0 处,我们可以获得字段的 x 和 y 分量及其位置。|| |当前代码如下:

当以颜色编码形式表示场的强度时,该函数起作用,但是当使用 quiver 函数绘制它时,我获得了您在图像中看到的内容。除了质量本身附近出现有趣的矢量之外,该场是正确的。我不认为这是除以零的错误,因为我在计算时忽略了这些错误。

import matplotlib.pyplot as plt
import numpy as np
import math

G = 6.674 * 10**(-11)

#Function to calculate gravitational field at each point on the screen caused by all other masses whose mass and positions are defined in lists along with the size of the screen and the components of the field
def gravfield(mass, x, y, screen_width, screen_height, give_components = False):

    #Define screen position points
    x_screen = list(range(screen_width))
    y_screen = list(range(screen_height))

    #Define empty array containing all field magnitudes at each pixel position of the screen along with empty field component lists and positions
    field = np.zeros((screen_width, screen_height))
    field_x = []
    field_y = []
    field_x_position = []
    field_y_position = []
        
    #Calculate the gravitational field from each mass by the vector method    
    for i in range(len(x_screen)):
        for n in range(len(y_screen)):

            #Define empty variable which will end up being the value of the field at a specific position after all mass contributions have been added
            x_field = 0
            y_field = 0
            
            for j in range(len(mass)):
                
                #Calculate position vector from the mass causing the field to the point affected
                x_distance = x[j] - x_screen[i]
                y_distance = y[j] - y_screen[n]
                distance = np.sqrt((x_distance**2) + (y_distance**2))
                
                if not math.isclose(distance, 0):
                        #Calculate the unit vector of the shortest path between the mass and point
                        x_unit_vector = x_distance / distance
                        y_unit_vector = y_distance / distance

                        #Calculate magnitude of the field
                        magnitude = (G * mass[j] * 1) / (distance ** 2)

                        #Calculate the component of the field in each direction and add them to the variable which contains the resultant field value at that position
                        x_field = (magnitude * x_unit_vector) + x_field
                        y_field = (magnitude * y_unit_vector) + y_field
                else:
                    pass
                
        #Add the resultant field component value and its position to the defined lists and calculate its magnitude which is assigned to an array where each position corresponds to a pixel on the screen

            #Only fill the field component lists if specified 
            if give_components == True:
                gx = x_field
                gy = y_field
                field_x.append(gx)
                field_y.append(gy)
                g = np.sqrt((gx**2) + (gy**2))
                field[n, i] = g
                field_x_position.append(i)
                field_y_position.append(n)
                
            else:
                gx = x_field
                gy = y_field
                g = np.sqrt((gx**2) + (gy**2))
                field[n, i] = g

    #Return the specified elements        
    if give_components == True:
        
        return field, field_x, field_y, field_x_position, field_y_position
    else:
        return field

mass = [400000000000000000000000, 800000000000000000000000]
x_cord = [10, 15]
y_cord = [10, 15]
screen_width = 20
screen_height = 20
give_components = True
field, field_x, field_y, field_x_position, field_y_position = gravfield(mass, x_cord, y_cord, screen_width, screen_height, give_components)



fig, ax = plt.subplots()

# Plot the vectors using quiver
ax.quiver(field_x_position, field_y_position, field_x, field_y)

# Set the x and y axis limits
ax.set_xlim([min(field_x_position), max(field_x_position)])
ax.set_ylim([min(field_y_position), max(field_y_position)])

# Show the plot
plt.show()

This function works when representing the intensity of the field in a color-coded form, but when plotting it with the quiver function I obtain what you can see in the image. The field is correct apart from near the mass itself where interesting vectors arise. I do not think it is a divide by zero error since those I just ignore when calculating.

Gravity field representation


代码的问题在于,你将整个屏幕宽度上的场分量附加到列表中,然后在循环的每次迭代中,你再次对整个屏幕高度执行此操作。这会导致你的向量位置不正确,从而导致绘图出现问题。

你需要做的是将 field_x field_y field_x_position field_y_position 列表的追加缩进到循环的内层,这样每次计算出一个新的场分量时,你都会将其附加到列表中,以及其相应的 x y 位置。

以下是更正后的代码:

import matplotlib.pyplot as plt
import numpy as np
import math

G = 6.674 * 10**(-11)

#Function to calculate gravitational field at each point on the screen caused by all other masses whose mass and positions are defined in lists along with the size of the screen and the components of the field
def gravfield(mass, x, y, screen_width, screen_height, give_components = False):

    #Define screen position points
    x_screen = list(range(screen_width))
    y_screen = list(range(screen_height))

    #Define empty array containing all field magnitudes at each pixel position of the screen along with empty field component lists and positions
    field = np.zeros((screen_width, screen_height))
    field_x = []
    field_y = []
    field_x_position = []
    field_y_position = []

    #Calculate the gravitational field from each mass by the vector method    
    for i in range(len(x_screen)):
        for n in range(len(y_screen)):

            #Define empty variable which will end up being the value of the field at a specific position after all mass contributions have been added
            x_field = 0
            y_field = 0

            for j in range(len(mass)):

                #Calculate position vector from the mass causing the field to the point affected
                x_distance = x[j] - x_screen[i]
                y_distance = y[j] - y_screen[n]
                distance = np.sqrt((x_distance**2) + (y_distance**2))

                if not math.isclose(distance, 0):
                        #Calculate the unit vector of the shortest path between the mass and point
                        x_unit_vector = x_distance / distance
                        y_unit_vector = y_distance / distance

                        #Calculate magnitude of the field
                        magnitude = (G * mass[j] * 1) / (distance ** 2)

                        #Calculate the component of the field in each direction and add them to the variable which contains the resultant field value at that position
                        x_field = (magnitude * x_unit_vector) + x_field
                        y_field = (magnitude * y_unit_vector) + y_field
                else:
                    pass

            # Add the resultant field component value and its position to the defined lists
            if give_components == True:
                gx = x_field
                gy = y_field
                field_x.append(gx)
                field_y.append(gy)
                g = np.sqrt((gx**2) + (gy**2))
                field[n, i] = g
                field_x_position.append(i)
                field_y_position.append(n)

            else:
                gx = x_field
                gy = y_field
                g = np.sqrt((gx**2) + (gy**2))
                field[n, i] = g

    #Return the specified elements        
    if give_components == True:

        return field, field_x, field_y, field_x_position, field_y_position
    else:
        return field

mass = [400000000000000000000000, 800000000000000000000000]
x_cord = [10, 15]
y_cord = [10, 15]
screen_width = 20
screen_height = 20
give_components = True
field, field_x, field_y, field_x_position, field_y_position = gravfield(mass, x_cord, y_cord, screen_width, screen_height, give_components)



fig, ax = plt.subplots()

# Plot the vectors using quiver
ax.quiver(field_x_position, field_y_position, field_x, field_y)

# Set the x and y axis limits
ax.set_xlim([min(field_x_position), max(field_x_position)])
ax.set_ylim([min(field_y_position), max(field_y_position)])

# Show the plot
plt.show()

通过这个更改,你的向量场现在应该可以正确绘制了。

标签:python,matplotlib,vector,gravity
From: 76650005

相关文章

  • 完全用python 实现消息中间件2
    为了完善这个简单的消息中间件,我们可以添加以下功能:消息持久化:虽然在这个示例中我们不会使用数据库,但我们可以将消息保存到文件中,以模拟持久化存储。消息确认:添加一个机制来确认消息已经被消费。并发控制:确保在多线程或多进程环境中消息的安全处理。以下是更新后的代码:fr......
  • 16:Python一些常用的变量命名
    变量名的命名直接影响到程序的易读性,好的变量名应该简洁、易于理解。一、单字符变量名数学中通常用x,y来表示坐标,同样的,在命名变量时,可以使用一些具有特定含义的单个字符。这样的变量名兼具有意义和极简两大优点,作为编程人员应熟记。具体列举如下。i、j、k:数值(integer(整数))......
  • 15:Python数据类型的综合对比整理
    #Python有六个标准的数据类型:#Numbers(数字)int#String(字符串)str字符串一旦创建,不可修改,一旦修改或者拼接,都会造成重新生成字符串#List(列表)list中号括起来,逗号分开,可以是数字、字符串、列表、布尔值,列表可以嵌套任何类型,列表有序元素可以被修改#Tup......
  • 用Python打造精彩动画与视频, 6.2 使用Manim进行数学和科学可视化
     6.2使用Manim进行数学和科学可视化Manim(MathematicalAnimationEngine)是一款强大的动画制作工具,尤其适用于数学和科学领域的可视化。它由3Blue1Brown的GrantSanderson开发,旨在通过动画演示复杂的数学概念,使其更易于理解。使用Manim,用户可以创建高质量的数学动画,从简单的......
  • 用Python打造精彩动画与视频,5.3 使用Manim创建简单动画
     5.3使用Manim创建简单动画在这一节中,我们将介绍如何使用Manim创建简单的动画。我们将从基本的场景构建开始,然后演示如何添加动画效果。通过这些示例,你将能够掌握使用Manim创建各种动画的基本技能。5.3.1创建一个简单的场景Manim中的基本单元是场景(Scene)。每个场景都是一......
  • 用Python打造精彩动画与视频, 5.2 安装和设置Manim
     5.2安装和设置ManimManim是一个强大的动画库,用于创建高质量的数学动画。它最初由3Blue1Brown的GrantSanderson开发,并被广泛用于教育和展示。以下是安装和设置Manim的详细步骤。5.2.1安装ManimManim需要Python环境和一些依赖库。在安装Manim之前,请确保已经......
  • 用Python打造精彩动画与视频,6.1 复杂动画场景的构建
     第六章:探索Manim的潜力6.1复杂动画场景的构建在本节中,我们将深入探索如何使用Manim构建复杂的动画场景。Manim是一款功能强大的Python库,广泛应用于数学可视化和教育视频制作。通过理解并掌握Manim的高级功能和技巧,你将能够创建出引人入胜且具有高可读性的动画场景。6.1.1......
  • 在 Python 中从 HTML 中抓取嵌入的 Google Sheet
    这对我来说相对棘手。我正在尝试提取来自python中的google工作表的嵌入表。这是链接我不拥有该工作表,但它是公开可用的。这是迄今为止我的代码,当我输出标题时,它向我显示“”。任何帮助将不胜感激。最终目标是将此表转换为pandasDF。多谢你们importlx......
  • 如何使用 Python 在 Google 或 DuckDuckGo 中快速获取答案
    我有一个人工智能助手项目,我希望它在互联网上搜索。我想使用适用于Python的GoogleQuickAnswerBox或DuckDuckGoInstantAnswerAPI。我看到了其他问题,但它们对我没有多大帮助。这是我想要实现的一个示例:问题:什么是长颈鹿?Google的答案:DuckDuckGo的......
  • 如何为可以在递归调用中重新分配的 python 函数制定类型提示?
    采取以下最小示例:S=TypeVar("S",bound=int|str)defmeth(a:S)->S:ifa=="5":returnstr(meth(int(a)))returna特别是,上面的方法可以采用字符串或整数。它总是返回与其输入相同类型的值,但它可以递归地调用自身,在这种情况下,S的值......