from scipy import *
import matplotlib.pyplot as plt


def plot_elines(x_grid, y_grid, potential, field):
    fig, ax = plt.subplots(figsize=(13, 13))
    im_cs = ax.contour(x_grid, y_grid, potential, 18, cmap='inferno')
    plt.clabel(im_cs, inline=1, fontsize=7)
    ax.quiver(x_grid[::3, ::3], y_grid[::3, ::3],
              field[0, ::3, ::3], field[1, ::3, ::3],)
    ax.set_xlabel("$x$")
    ax.set_ylabel("$y$")
    plt.show()


# define q configuration (x,y positions)
charges = [
    [1, 1],
]

xx, yy = meshgrid(linspace(-4, 4), linspace(-4, 4))
# potential function
e_pot = 0.
for idx, q in enumerate(charges):
    dx, dy = xx-q[0], yy-q[1]
    rr = hypot(dx, dy)
    e_pot += 1/(4*pi) * 1./rr
e_field = gradient(-e_pot)
e_field /= hypot(e_field[0], e_field[1]) * 5

# why is this needed?
e_field[0] = e_field[0].T
e_field[1] = e_field[1].T

plot_elines(xx, yy, e_pot, e_field)


我对从numpy / scipy使用gradient函数有疑问。

我在这里绘制电场等势线和单个正电荷的场矢量。定义是


  E = -grad(V)


根据定义,场矢量(颤动线)和等势线(轮廓线)应该在空间的所有点处彼此正交,并且由于电荷为正,因此箭头需要指向远离电荷本身的方向。

我正在使用scipy的gradient函数计算E,但我发现如果不对gradient函数的x-y网格输出进行转置,则输出错误。

比较两个输出(.T(正确)和.T(错误)):





为什么需要移调?还是我画错了什么?

谢谢。

最佳答案

换位为您提供正确图的事实纯属巧合,因为电荷在x和y中对称分布(即在45°线上)。

真正的问题来自对numpy.gradient的错误解释。它将沿轴向返回渐变。轴0的第一个数组,轴1的第二个数组。现在,在您的情况下,轴0对应y轴,轴1对应x轴。

e_field_y, e_field_x = numpy.gradient(-e_pot)


因此,当在颤动图中选择各个字段分量时,需要选择第一个条目作为y分量,选择第二个条目作为x分量。

ax.quiver(x_grid[::3, ::3], y_grid[::3, ::3],
          field[1, ::3, ::3], field[0, ::3, ::3],)


完整的代码将如下所示

import numpy as np
import matplotlib.pyplot as plt


def plot_elines(x_grid, y_grid, potential, field):
    fig, ax = plt.subplots(figsize=(13, 13))
    im_cs = ax.contour(x_grid, y_grid, potential, 18, cmap='inferno')
    plt.clabel(im_cs, inline=1, fontsize=7)
    ax.quiver(x_grid[::3, ::3], y_grid[::3, ::3],
              field[1, ::3, ::3], field[0, ::3, ::3],)
    ax.set_xlabel("$x$")
    ax.set_ylabel("$y$")
    ax.set_aspect("equal")
    plt.show()


# define q configuration (x,y positions)
charges = [
    [1, 0],
]

xx, yy = np.meshgrid(np.linspace(-4, 4), np.linspace(-4, 4))
# potential function
e_pot = 0.
for idx, q in enumerate(charges):
    dx, dy = xx-q[0], yy-q[1]
    rr = np.hypot(dx, dy)
    e_pot += 1/(4*np.pi) * 1./rr
e_field = np.gradient(-e_pot)
e_field /= np.hypot(e_field[0], e_field[1]) * 5

plot_elines(xx, yy, e_pot, e_field)


在这里我将费用从反对角线中剔除。

python - 梯度和颤动图-LMLPHP

最后提示:如果使用不同形状的网格,则对此类代码进行良好的一致性检查。例如。如果沿x取50分,沿y取51分,那么您将得到一个错误,而不是看似有效的代码,并且会更容易地针对基本问题。

关于python - 梯度和颤动图,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54471306/

10-12 18:20