当前位置: 首页 > 知识库问答 >
问题:

Python中两个图的交集,找到x值

东郭自珍
2023-03-14

让0

plt.plot(x, f, '-')
plt.plot(x, g, '*')

我想找到曲线相交的点“x”。我不想找到f和g的交点。我可以通过以下方法简单地找到:

set(f) & set(g)

共有3个答案

郭翰墨
2023-03-14

以下是一个解决方案:

  • 适用于N维数据
  • 使用欧几里德距离,而不仅仅是在y轴上查找交叉点
  • 对于大量数据更有效(它查询KD树,KD树应该以对数时间而不是线性时间进行查询)
  • 您可以在KD树查询中更改距离上限,以定义距离是否足够近
  • 如果需要,您可以同时查询具有多个点的KD树。注意:如果您需要一次查询数千个点,您可以通过使用另一个KD树查询KD树来显著提高性能
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.spatial import cKDTree
from scipy import interpolate

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1], projection='3d')
ax.axis('off')

def upsample_coords(coord_list):
    # s is smoothness, set to zero
    # k is degree of the spline. setting to 1 for linear spline
    tck, u = interpolate.splprep(coord_list, k=1, s=0.0)
    upsampled_coords = interpolate.splev(np.linspace(0, 1, 100), tck)
    return upsampled_coords

# target line
x_targ = [1, 2, 3, 4, 5, 6, 7, 8]
y_targ = [20, 100, 50, 120, 55, 240, 50, 25]
z_targ = [20, 100, 50, 120, 55, 240, 50, 25]
targ_upsampled = upsample_coords([x_targ, y_targ, z_targ])
targ_coords = np.column_stack(targ_upsampled)

# KD-tree for nearest neighbor search
targ_kdtree = cKDTree(targ_coords)

# line two
x2 = [3,4,5,6,7,8,9]
y2 = [25,35,14,67,88,44,120]
z2 = [25,35,14,67,88,44,120]
l2_upsampled = upsample_coords([x2, y2, z2])
l2_coords = np.column_stack(l2_upsampled)

# plot both lines
ax.plot(x_targ, y_targ, z_targ, color='black', linewidth=0.5)
ax.plot(x2, y2, z2, color='darkgreen', linewidth=0.5)

# find intersections
for i in range(len(l2_coords)):
    if i == 0:  # skip first, there is no previous point
        continue

    distance, close_index = targ_kdtree.query(l2_coords[i], distance_upper_bound=.5)

    # strangely, points infinitely far away are somehow within the upper bound
    if np.isinf(distance):
        continue

    # plot ground truth that was activated
    _x, _y, _z = targ_kdtree.data[close_index]
    ax.scatter(_x, _y, _z, 'gx')
    _x2, _y2, _z2 = l2_coords[i]
    ax.scatter(_x2, _y2, _z2, 'rx')  # Plot the cross point


plt.show()
赵飞语
2023-03-14

对于那些正在使用或开放使用Shapely库进行几何体相关计算的人来说,获取交点会容易得多。您只需从每条线构造LineString,并获得它们的交点,如下所示:

import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import LineString

x = np.arange(0, 1000)
f = np.arange(0, 1000)
g = np.sin(np.arange(0, 10, 0.01) * 2) * 1000

plt.plot(x, f)
plt.plot(x, g)

first_line = LineString(np.column_stack((x, f)))
second_line = LineString(np.column_stack((x, g)))
intersection = first_line.intersection(second_line)

if intersection.geom_type == 'MultiPoint':
    plt.plot(*LineString(intersection).xy, 'o')
elif intersection.geom_type == 'Point':
    plt.plot(*intersection.xy, 'o')

要获得xy值作为NumPy数组,您只需编写:

x, y = LineString(intersection).xy
# x: array('d', [0.0, 149.5724669847373, 331.02906176584617, 448.01182730277833, 664.6733061190541, 743.4822641140581])
# y: array('d', [0.0, 149.5724669847373, 331.02906176584617, 448.01182730277833, 664.6733061190541, 743.4822641140581])

或者,如果交点仅为一个点:

x, y = intersection.xy
巩光誉
2023-03-14

您可以使用np。与np组合使用符号。差异np。argwhere获取线交叉点的索引(在本例中,点是[0、149、331、448、664、743]):

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 1000)
f = np.arange(0, 1000)
g = np.sin(np.arange(0, 10, 0.01) * 2) * 1000

plt.plot(x, f, '-')
plt.plot(x, g, '-')

idx = np.argwhere(np.diff(np.sign(f - g))).flatten()
plt.plot(x[idx], f[idx], 'ro')
plt.show()

首先,它使用np计算f-g和相应的符号。签名。应用np。diff显示符号变化的所有位置(例如,线交叉)。使用np。argwhere为我们提供了准确的索引。

 类似资料:
  • 问题内容: 我知道如何得到两个平面列表的交集: 但是当我必须找到嵌套列表的交集时,我的问题就开始了: 最后,我希望收到: 你们能帮我这个忙吗? 问题答案: 如果你想: 然后这是你的Python 2解决方案: 在Python 3 返回一个迭代,而不是,所以你需要用filter与呼叫list(): 说明: 过滤器部分接受每个子列表的项目,并检查它是否在源列表c1中。对c2中的每个子列表执行列表推导。

  • 问题内容: 我有一个可能很简单的问题,这使我已经安静了一段时间。有没有一种简单的方法来返回python matplotlib中两个绘制的(非分析性)数据集的交集? 为了详细说明,我有这样的东西: 本示例中的数据完全是任意的。现在,我想知道是否有一个简单的内置函数会丢失,该函数会向我返回两个图之间的精确交点。 希望我能说清楚自己,也希望我没有错过任何显而易见的事情。 问题答案: 我们可以用来创建由分

  • 我已经读过一些其他的堆栈溢出线程: 在java中求两个多集的交集 我如何获得两个数组之间的交集作为一个新数组? 我试图检查两个数组以及它们的元素数(numElementsInX和numElementsInY),并返回一个包含数组x和y的公共值的新数组。他们的交集。 编辑代码

  • 问题内容: 这个问题已经在这里有了答案 : 从列表列表中删除重复项 (12个答案) 4年前关闭。 这是我的两个清单。 我的输出应为以下内容; 如何获得此输出? 先感谢您 问题答案: 您将必须将列表转换为元组列表,然后使用交集。请注意,下面的解决方案可能具有不同顺序的元素,并且由于我使用的是set,因此显然不会存在重复项。 您也可以将交叉点保存在变量中并获取最终列表,如果需要排序,则需要重复: 和交

  • 问题内容: 实际输出: 预期输出: 我们如何在两个列表上实现布尔AND操作(列表交集)? 问题答案: 如果顺序不重要,并且你不必担心重复,则可以使用set相交:

  • 如果这两个矩阵不是无序的,长度相同,那么下面的代码应该可以工作,并且是有效的。 我的一个老练的解决方案是将我要用于匹配的每个矩阵的各个列串联起来。在本例中,我将使用所有列。 这就是我正在寻找的结果,但我想知道是否有更优雅的东西,比如%中的向量函数