matplotlib 从4个点创建椭圆

5gfr0r5j  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(157)

我试图做一个非常基本的形状连接4点.我有一个情节,目前看起来像this.然而,我似乎找不到一个模块,可以适当地生成一个椭圆连接所有四个点.这四个点都将有所不同(它们是测试的结果,旨在显示某人拥有多少每个属性)。我发现了许多模块来创建矩形,椭圆或圆形,但是这些形状都不会与点一致地对齐。有没有一个更通用的模块可以将所有四个点连接成一个更像椭圆的形状?
我也看到了一些模块,可以创建两点之间的弧,我认为这可能是有用的,我可以这样做的所有四个点。当我试图这样做,它需要输入相关的弧角,我不会知道如何计算。任何帮助这是非常感谢!
下面是我用来生成所示图像的代码。

import matplotlib.pyplot as plt
import numpy as np

# Axes go from 0 to 100%
fig,ax = plt.subplots(figsize=(15,12))

x = [-40,-20,20,20]
y = [-40,20,20,-20]

plt.scatter(x,y)
ax.fill_between([-100, 0],-100,0,alpha=0.3, color='#1F98D0')  # blue
ax.fill_between([0, 100], -100, 0, alpha=0.3, color='#F9D307')  # yellow
ax.fill_between([-100, 0], 0, 100, alpha=0.3, color='#F38D25')  # orange
ax.fill_between([0, 100], 0, 100, alpha=0.3, color='#DA383D')  # red
plt.axis('off')
plt.show()
kiayqfof

kiayqfof1#

下面的方法通过4个点创建一个interpolating spline来创建一个“基本形式”。一个优点是,当有3个或4个以上的点时,它也有效。

import matplotlib.pyplot as plt
from scipy import interpolate
import numpy as np

fig, ax = plt.subplots(figsize=(15, 12))

x = [-40, -20, 20, 20]
y = [-40, 20, 20, -20]

ax.scatter(x, y, zorder=3)
ax.fill_between([-100, 0], -100, 0, alpha=0.3, color='#1F98D0')  #blue
ax.fill_between([0, 100], -100, 0, alpha=0.3, color='#F9D307')  #yellow
ax.fill_between([-100, 0], 0, 100, alpha=0.3, color='#F38D25')  #orange
ax.fill_between([0, 100], 0, 100, alpha=0.3, color='#DA383D')  #red

tck, u = interpolate.splprep([x + x[:1], y + y[:1]], s=0, per=True)
unew = np.linspace(0, 1, 100)
basic_form = interpolate.splev(unew, tck)
ax.plot(basic_form[0], basic_form[1], color='lime', lw=2)
ax.fill(basic_form[0], basic_form[1], color='lime', alpha=0.3)

ax.axis('off')
plt.show()

同样的方法也适用于椭圆形不可能适合或太大的情况:

注意to uniquely define an ellipse,需要5个点(但不是每5个随机点都能拟合一个椭圆)。如果你真的需要一个椭圆,通过4个点找到最小的一个是相当麻烦的。
这里是一个方法的开始,它将椭圆定义为到两个焦点((x0,y0)(x1,y1))的距离之和为常数a的点,然后可以搜索存在解的某个最小值a

from sympy import symbols, sqrt, Eq, nsolve

a, x0, y0, x1, y1, xi, yi = symbols('a x0 y0 x1 y1 xi yi', real=True)
ellipse = Eq(sqrt((xi - x0) ** 2 + (yi - y0) ** 2) + sqrt((xi - x1) ** 2 + (yi - y1) ** 2), a)

x = [-40, -20, 20, 20]
y = [-40, 20, 20, -20]

ai = 85
sol = nsolve([ellipse.subs(xi, i).subs(yi, j).subs(a, ai) for i, j in zip(x, y)], (x0, y0, x1, y1), (-10, 0, 10, 0))

相关问题