在点

时间:2015-06-06 11:20:04

标签: python matplotlib geometry ellipse

我正在尝试使用matplotlib在图表上围绕组的点绘制省略号。我想得到这样的东西:

enter image description here

组的数据集(例如红色)可能如下所示:

[[-23.88315146  -3.26328266]  # first point
 [-25.94906669  -1.47440904]  # second point
 [-26.52423229  -4.84947907]]  # third point

我可以轻松地在图表上绘制点,但是我会遇到绘制省略号的问题。

椭圆的直径为2 * standard deviation,其中心的坐标为(x_mean, y_mean)。一个椭圆的宽度等于x standard deviation * 2。它的高度等于y standard deviation * 2

但是,我不知道如何计算椭圆的角度(你可以在图片上看到椭圆不是完全垂直的)。

你对如何做到了吗?

注意: 这个问题是LDA问题的简化(线性判别分析)。我正在尝试将问题简化为最基本的表达方式。

2 个答案:

答案 0 :(得分:0)

这与数学有很大关系,而不是编程;)

由于你已经拥有尺寸并且只想找到角度,这就是我要做的事情(基于我的直觉):

尝试找到最适合给定点集(趋势线)的线,这也称为Linear Regression。有几种方法可以做到这一点,但最小二乘方法相对简单(见下文)。

找到最佳拟合线后,可以使用斜率作为角度。

最小二乘线性回归

最小二乘线性回归方法用于找出趋势线的斜率,正是我们想要的。

这是video explaining how it works

假设您有一个数据集:data = [(x1, y1), (x2, y2), ...]

使用最小二乘法,您的斜率为:

# I see in your example that you already have x_mean and y_mean
# No need to calculate them again, skip the two following lines
# and use your values in the rest of the example
avg_x = sum(element[0] for element in data)/len(data)
avg_y = sum(element[1] for element in data)/len(data)

x_diff = [element[0] - avg_x for element in data]
y_diff = [element[1] - avg_y for element in data]

x_diff_squared = [element**2 for element in x_diff]

slope = sum(x * y for x,y in zip(x_diff, y_diff)) / sum(x_diff_squared)

一旦你拥有了,你就快完成了。斜率等于角度slope = tan(angle)

的正切值

使用python' math模块angle = math.atan(slope)这将以弧度返回角度。如果你想要它以度为单位,你必须使用math.degrees(angle)

进行转换

将它与你已经拥有的尺寸和位置相结合,你得到了一个椭圆;)

这就是我如何解决这个特殊问题,但可能还有一千种不同的方法也可以解决 并且最终可能比我建议的更好(也更复杂)。

答案 1 :(得分:0)

这是一个经过充分研究的问题。首先取一组点的convex hull 你想附上。然后执行文献中描述的计算。 我在下面提供两个来源。

  

“最小的枚举椭圆 - C ++中的精确和通用实现”(abstract link)。

<小时/> Ellipse

  

Charles F. Van Loan。 “使用椭圆来拟合和包含数据点。”   (PDF download)。