我试图找到矢量场中会聚的区域或点。
我已使用下面的代码生成以下图:
import matplotlib.pyplot as plt
import numpy as np
def generate_fake_data():
return -(np.sin(X) * np.cos(Y) + np.cos(X)), -(-np.cos(X) * np.sin(Y) + np.sin(Y))
x = np.arange(0, 2 * np.pi + 2 * np.pi / 20, 2 * np.pi / 20)
y = np.arange(0, 2 * np.pi + 2 * np.pi / 20, 2 * np.pi / 20)
X, Y = np.meshgrid(x, y)
u, v = generate_fake_data()
fig, ax = plt.subplots(figsize=(7, 7))
# quiveropts = dict(headlength=0, headaxislength=0, pivot='middle', units='xy')
# ax.quiver(X, Y, u, v, **quiveropts)
ax.quiver(X, Y, u, v)
ax.xaxis.set_ticks([])
ax.yaxis.set_ticks([])
ax.axis([0, 2 * np.pi, 0, 2 * np.pi])
ax.set_aspect('equal')
ax.axis("off")
plt.gca().set_axis_off()
plt.subplots_adjust(top=1, bottom=0, right=1, left=0,
hspace=0, wspace=0)
plt.margins(0, 0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.savefig("mock_data.png", bbox_inches='tight', pad_inches=0)
理想情况下,我所追求的是在图像的右上角和右下角找到该矢量场中的收敛点。
我希望可以使用curl值来实现此目的,但是任何一种方法都可以使用。
此外,这只是概念上的证明,generate_fake_data
将被替换为从可变的其他位置读取数据的函数。
答案 0 :(得分:1)
对于收敛点,矢量场的散度为<0。
from functools import reduce
conv = reduce(np.add,np.gradient(u)) + reduce(np.add,np.gradient(v))
(请参见Compute divergence of vector field using python)
我们只需要负偏差:
conv[conv>=0] = np.nan
plt.imshow(conv)
:字段越暗,收敛越多:
找到绝对最小值(在右上角)很容易:
absmin = np.unravel_index(np.nanargmin(conv), conv.shape)
print(absmin, conv[absmin])
#(0, 15) -0.6669774724547413
查找相对最小值比较困难,argrelmin
应该可以,但是坦白地说,我无法正确地返回第二个局部最小值(19,15)。
使用this answer我得到
lm = detect_local_minima(conv)
list(zip(lm))
[(0, 15), (1, 0), (19, 15), (20, 0)]
在左上角还包含两个最小值(在数学上是正确的,但在我们的情况下不希望如此,因此也许我们可以只排除四个角)。