2015-06-06 6 views
2

Я пытаюсь нарисовать эллипсы вокруг точек группы на графике, с 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 (линейный дискриминантный анализ). Я пытаюсь упростить проблему до самого ее основного выражения.

ответ

0

Это имеет гораздо больше общего с математикой, чем программирование;)

Поскольку у вас уже есть размеры и только хотят, чтобы найти угол, вот что я хотел бы сделать (на основе моего инстинкта):

Попробуйте найти линию, которая наилучшим образом соответствует данному набору точек (линия тренда), это также называется Linear Regression. Есть несколько способов сделать это, но метод Least Squares относительно прост (см. Ниже).

Как только вы нашли лучшую линию фитинга, вы можете использовать наклон в качестве угла.

наименьших квадратов линейной регрессии

наименьших квадратов Метод линейной регрессии используется, чтобы найти наклон трендовой, именно то, что мы хотим.

Вот 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)

Используйте модуль math python angle = math.atan(slope), это вернет угол в радианах.Если вы хотите в градусах вы должны преобразовать его с помощью math.degrees(angle)

Объедините это с размерами и положением у вас уже есть, и вы получили себе эллипс;)


Это, как я хотел бы решить этот конкретный проблема, но есть, вероятно, тысяча различных методов, которые бы работали слишком и могут быть в конечном итоге лучше (и сложнее), чем то, что я предлагаю.

-1

Это хорошо изученная проблема. Сначала возьмите convex hull из набора пунктов , которые вы хотите приложить. Затем выполните вычисления, как описано в литературе. Я предоставляю два источника ниже.

«Наименьшие замкнутые эллипсы - точная и общая реализация на C++» (abstract link).


          Ellipse


Charles F. Van Loan. «Использование эллипса для подбора и добавления точек данных». (PDF download).

Смежные вопросы