检查点在椭圆内的速度是否比contains_point方法快 [英] Check if points are inside ellipse faster than contains_point method

查看:45
本文介绍了检查点在椭圆内的速度是否比contains_point方法快的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 matplotlib 1.15.1 并尝试生成这样的散点图:

I use matplotlib 1.15.1 and I try to generate scattergrams like this:

椭圆有固定的大小,并用中心坐标、宽度、高度和角度(从外部提供)绘制:我不知道它们的引用是什么.

The ellipses have fixes size and are drawn with center coordinates, width, height and angle (provided from outside): I have no idea what their equotions are.

g_ell_center = (0.8882, 0.8882)
g_ell_width = 0.36401857095483
g_ell_height = 0.16928136341606
g_ellipse = patches.Ellipse(g_ell_center, g_ell_width, g_ell_height, angle=angle, fill=False, edgecolor='green', linewidth=2)

这个椭圆应该在我的图中标记正常和半正常数据.然后,我有一个〜500点的数组,必须根据它们所属的椭圆对其进行着色.所以我试着用 contains_point 方法检查每个点:

This ellipses should mark normal and semi-normal data on my plot. Then, I have an array of ~500 points which must be colored according to ellipse they belong to. So I tried to check each point with contains_point method:

colors_array = []
colors_scheme = ['green', 'yellow', 'black']
for point in points_array:
    if g_ellipse.contains_point(point, radius=0):
        colors_array.append(0)
    elif y_ellipse.contains_point(point, radius=0):
        colors_array.append(1)
    else:
        colors_array.append(2)

最后,绘制点:

plt.scatter(x_array, y_array, s=10, c=[colors_scheme[x] for x in colors_array], edgecolor="k", linewidths=0.3)

但是 contains_point 非常慢!它为300点散点图工作了5分钟,我必须并行生成数千个散点图.也许有更快的方法?P.S.整个项目绑定到matplotlib,我不能使用其他库.

But contains_point is extremely slow! It worked for 5 minutes for 300-points scattergram, and I have to generate thousands of them in parallel. Maybe there's faster approach? P.S. Whole project is bound to matplotlib, I can't use other libraries.

推荐答案

这种方法应该测试一个点是否在椭圆内,给定椭圆的中心、宽度、高度和角度.您可以找到该点相对于椭圆中心的x和y坐标,然后使用该角度将其转换为沿长轴和短轴的坐标.最后,您找到该点到像元中心的标准化距离,其中椭圆上的距离为1,内部小于1,外部为1.

This approach should test if a point is within an ellipse, given the ellipse's centre, width, height and angle. You find the point's x and y coordinates relative to the ellipse centre, then transform those using the angle to be the coordinates along the major and minor axes. Finally, you find the normalised distance of the point from the cell centre, where a distance of 1 would be on the ellipse, less than 1 is inside, and more than 1 is outside.

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

fig,ax = plt.subplots(1)
ax.set_aspect('equal')

# Some test points
x = np.random.rand(500)*0.5+0.7
y = np.random.rand(500)*0.5+0.7

# The ellipse
g_ell_center = (0.8882, 0.8882)
g_ell_width = 0.36401857095483
g_ell_height = 0.16928136341606
angle = 30.

g_ellipse = patches.Ellipse(g_ell_center, g_ell_width, g_ell_height, angle=angle, fill=False, edgecolor='green', linewidth=2)
ax.add_patch(g_ellipse)

cos_angle = np.cos(np.radians(180.-angle))
sin_angle = np.sin(np.radians(180.-angle))

xc = x - g_ell_center[0]
yc = y - g_ell_center[1]

xct = xc * cos_angle - yc * sin_angle
yct = xc * sin_angle + yc * cos_angle 

rad_cc = (xct**2/(g_ell_width/2.)**2) + (yct**2/(g_ell_height/2.)**2)

# Set the colors. Black if outside the ellipse, green if inside
colors_array = np.array(['black'] * len(rad_cc))
colors_array[np.where(rad_cc <= 1.)[0]] = 'green'

ax.scatter(x,y,c=colors_array,linewidths=0.3)

plt.show()

注意,整个脚本需要 0.6 秒来运行和处理 500 个点.其中包括创建和保存图形等.

Note, this whole script takes 0.6 seconds to run and process 500 points. That includes creating and saving the figure, etc.

使用上述 np.where 方法设置colors_array的过程需要0.00007秒(500点).

The process of setting the colors_array using the np.where method above takes 0.00007s for 500 points.

注意,在下面显示的较旧的实现中,在一个循环中设置colors_array花费了0.00016 s:

Note, in an older implementation shown below, setting the colors_array in a loop took 0.00016 s:

colors_array = []

for r in rad_cc:
    if r <= 1.:
        # point in ellipse
        colors_array.append('green')
    else:
        # point not in ellipse
        colors_array.append('black')

这篇关于检查点在椭圆内的速度是否比contains_point方法快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆