如何计算 Python 中 2 个等高线之间的点数
How can I count number of points between 2 contours in Python
我正在使用 matplotlib.pyplot
来插值我的数据并创建轮廓。
按照this answer/example(关于如何计算等高线内的面积),我能够得到等高线的顶点。
有没有办法使用该信息(即一条线的顶点)来计算两个给定轮廓之间有多少点?这些点将与用于导出等值线的数据不同。
我不确定我是否理解你想要检查哪些点,但是,如果你有线顶点(两个点)并且想检查第三个点是否落在两者之间,你可以采取简单(效率不高)的方法并计算由三者形成的三角形的面积。如果面积为 0,则点落在同一条线上。另外,您可以计算点与点之间的距离,并查看该点是在直线之间还是在(延长)直线之外。
希望对您有所帮助!
通常,您不想通过逆向工程来获取一些数据。相反,您可以对稍后用于绘制等高线的数组进行插值,并找出哪些点位于特定值的区域中。
以下将找到 -0.8
和 -0.4
水平之间的所有点,打印它们并在图上以红色显示。
import numpy as np; np.random.seed(1)
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
from scipy.interpolate import Rbf
X, Y = np.meshgrid(np.arange(-3.0, 3.0, 0.1), np.arange(-2.4, 1.0, 0.1))
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
Z = 10.0 * (Z2 - Z1)
points = np.random.randn(15,2)/1.2
levels = [-1.2, -0.8,-0.4,-0.2]
# interpolate points
f = Rbf(X.flatten(), Y.flatten(), Z.flatten())
zi = f(points[:,0], points[:,1])
# add interpolated points to array with columns x,y,z
points3d = np.zeros((points.shape[0],3))
points3d[:,:2] = points
points3d[:,2] = zi
# masking condition for points between levels
filt = (zi>levels[1]) & (zi <levels[2])
# print points between the second and third level
print(points3d[filt,:])
### plotting
fig, ax = plt.subplots()
CS = ax.contour(X, Y, Z, levels=levels)
ax.clabel(CS, inline=1, fontsize=10)
#plot points between the second and third level in red:
ax.scatter(points[:,0], points[:,1], c=filt.astype(float), cmap="bwr" )
plt.show()
Ampere's law of magnetic fields 在这里可以提供帮助 - 尽管它可能在计算上很昂贵。这个定律说的是磁场沿闭合回路的路径积分与回路内的电流成正比。
假设您有一个轮廓 C 和一个点 P (x0,y0)。想象一下位于 P 处的无限导线垂直于页面(电流进入页面)承载一些电流。使用安培定律我们可以证明,导线在点 P (x,y) 处产生的磁场与从 (x0,y0) 到 (x,y) 的距离成反比,并且与以点 P 为中心的圆相切通过点 (x,y)。因此,如果导线位于轮廓之外,则路径积分为零。
import numpy as np
import pylab as plt
# generating a mesh and values on it
delta = 0.1
x = np.arange(-3.1*2, 3.1*2, delta)
y = np.arange(-3.1*2, 3.1*2, delta)
X, Y = np.meshgrid(x, y)
Z = np.sqrt(X**2 + Y**2)
# generating the contours with some levels
levels = [1.0]
plt.figure(figsize=(10,10))
cs = plt.contour(X,Y,Z,levels=levels)
# finding vertices on a particular level
contours = cs.collections[0]
vertices_level = contours.get_paths()[0].vertices # In this example the
shape of vertices_level is (161,2)
# converting points into two lists; one per dimension. This step can be optimized
lX, lY = list(zip(*vertices_level))
# computing Ampere's Law rhs
def AmpereLaw(x0,y0,lX,lY):
S = 0
for ii in range(len(lX)-1):
dx = lX[ii+1] - lX[ii]
dy = lY[ii+1] - lY[ii]
ds = (1/((lX[ii]-x0)**2+(lY[ii]-y0)**2))*(-(lY[ii]-y0)*dx+(lX[ii]-x0)*dy)
if -1000 < ds < 1000: #to avoid very lare numbers when denominator is small
S = S + ds
return(S)
# we know point (0,0) is inside the contour
AmpereLaw(0,0,lX,lY)
# result: -6.271376740062852
# we know point (0,0) is inside the contour
AmpereLaw(-2,0,lX,lY)
# result: 0.00013279920934375876
您可以使用此结果查找一个轮廓内但另一个轮廓外的点。
我正在使用 matplotlib.pyplot
来插值我的数据并创建轮廓。
按照this answer/example(关于如何计算等高线内的面积),我能够得到等高线的顶点。
有没有办法使用该信息(即一条线的顶点)来计算两个给定轮廓之间有多少点?这些点将与用于导出等值线的数据不同。
我不确定我是否理解你想要检查哪些点,但是,如果你有线顶点(两个点)并且想检查第三个点是否落在两者之间,你可以采取简单(效率不高)的方法并计算由三者形成的三角形的面积。如果面积为 0,则点落在同一条线上。另外,您可以计算点与点之间的距离,并查看该点是在直线之间还是在(延长)直线之外。
希望对您有所帮助!
通常,您不想通过逆向工程来获取一些数据。相反,您可以对稍后用于绘制等高线的数组进行插值,并找出哪些点位于特定值的区域中。
以下将找到 -0.8
和 -0.4
水平之间的所有点,打印它们并在图上以红色显示。
import numpy as np; np.random.seed(1)
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
from scipy.interpolate import Rbf
X, Y = np.meshgrid(np.arange(-3.0, 3.0, 0.1), np.arange(-2.4, 1.0, 0.1))
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
Z = 10.0 * (Z2 - Z1)
points = np.random.randn(15,2)/1.2
levels = [-1.2, -0.8,-0.4,-0.2]
# interpolate points
f = Rbf(X.flatten(), Y.flatten(), Z.flatten())
zi = f(points[:,0], points[:,1])
# add interpolated points to array with columns x,y,z
points3d = np.zeros((points.shape[0],3))
points3d[:,:2] = points
points3d[:,2] = zi
# masking condition for points between levels
filt = (zi>levels[1]) & (zi <levels[2])
# print points between the second and third level
print(points3d[filt,:])
### plotting
fig, ax = plt.subplots()
CS = ax.contour(X, Y, Z, levels=levels)
ax.clabel(CS, inline=1, fontsize=10)
#plot points between the second and third level in red:
ax.scatter(points[:,0], points[:,1], c=filt.astype(float), cmap="bwr" )
plt.show()
Ampere's law of magnetic fields 在这里可以提供帮助 - 尽管它可能在计算上很昂贵。这个定律说的是磁场沿闭合回路的路径积分与回路内的电流成正比。
假设您有一个轮廓 C 和一个点 P (x0,y0)。想象一下位于 P 处的无限导线垂直于页面(电流进入页面)承载一些电流。使用安培定律我们可以证明,导线在点 P (x,y) 处产生的磁场与从 (x0,y0) 到 (x,y) 的距离成反比,并且与以点 P 为中心的圆相切通过点 (x,y)。因此,如果导线位于轮廓之外,则路径积分为零。
import numpy as np
import pylab as plt
# generating a mesh and values on it
delta = 0.1
x = np.arange(-3.1*2, 3.1*2, delta)
y = np.arange(-3.1*2, 3.1*2, delta)
X, Y = np.meshgrid(x, y)
Z = np.sqrt(X**2 + Y**2)
# generating the contours with some levels
levels = [1.0]
plt.figure(figsize=(10,10))
cs = plt.contour(X,Y,Z,levels=levels)
# finding vertices on a particular level
contours = cs.collections[0]
vertices_level = contours.get_paths()[0].vertices # In this example the
shape of vertices_level is (161,2)
# converting points into two lists; one per dimension. This step can be optimized
lX, lY = list(zip(*vertices_level))
# computing Ampere's Law rhs
def AmpereLaw(x0,y0,lX,lY):
S = 0
for ii in range(len(lX)-1):
dx = lX[ii+1] - lX[ii]
dy = lY[ii+1] - lY[ii]
ds = (1/((lX[ii]-x0)**2+(lY[ii]-y0)**2))*(-(lY[ii]-y0)*dx+(lX[ii]-x0)*dy)
if -1000 < ds < 1000: #to avoid very lare numbers when denominator is small
S = S + ds
return(S)
# we know point (0,0) is inside the contour
AmpereLaw(0,0,lX,lY)
# result: -6.271376740062852
# we know point (0,0) is inside the contour
AmpereLaw(-2,0,lX,lY)
# result: 0.00013279920934375876
您可以使用此结果查找一个轮廓内但另一个轮廓外的点。