绘制连接两个点而不是直线的曲线

时间:2015-05-02 22:42:23

标签: python matplotlib

我想做这样的事情:
enter image description here

我有点但不知道如何绘制曲线而不是直线。

谢谢。

3 个答案:

答案 0 :(得分:3)

对于对此问题感兴趣的人,我遵循了Matthew的建议并提出了以下实施方案:

def hanging_line(point1, point2):
    import numpy as np

    a = (point2[1] - point1[1])/(np.cosh(point2[0]) - np.cosh(point1[0]))
    b = point1[1] - a*np.cosh(point1[0])
    x = np.linspace(point1[0], point2[0], 100)
    y = a*np.cosh(x) + b

    return (x,y)

结果如下:

import matplotlib.pyplot as plt

point1 = [0,1]
point2 = [1,2]
x,y = hanging_line(point1, point2)

plt.plot(point1[0], point1[1], 'o')
plt.plot(point2[0], point2[1], 'o')
plt.plot(x,y)

§1

答案 1 :(得分:1)

您需要为要绘制的曲线设置一些表达式,然后可以从许多线段中创建曲线。

这是抛物线:

x = np.linspace(-1, 1, 100)
y = x*x
plt.plot(x, y)

parabola

这是一条罪恶曲线:

x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = np.sin(x)
plt.plot(x, y)

sin

每个看起来都很流畅,但实际上是由许多小线段组成的。

要获得您所展示的曲线集合,您需要根据其两个端点绘制要绘制曲线的表达式。你图片中的那些看起来像catenarys,它们是(大约)悬挂链在重力作用下呈现的形状:

x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = 2*np.cosh(x/2)
plt.plot(x, y)

catenary

您必须找到一种根据两个端点对此曲线进行参数化的方法,这将要求您将y和x的值替换为:

y = a*cosh(x/a) + b

并求解a和b的结果方程对。

答案 2 :(得分:1)

有一种很酷的方法(至少对我而言),使用Bezier curves在两点之间绘制曲线。只需一些简单的代码,您就可以创建带有连接点的点的列表,并使用matplotlib对其进行制图,例如:

def recta(x1, y1, x2, y2):
    a = (y1 - y2) / (x1 - x2)
    b = y1 - a * x1
    return (a, b)

def curva_b(xa, ya, xb, yb, xc, yc):
    (x1, y1, x2, y2) = (xa, ya, xb, yb)
    (a1, b1) = recta(xa, ya, xb, yb)
    (a2, b2) = recta(xb, yb, xc, yc)
    puntos = []

    for i in range(0, 1000):
        if x1 == x2:
            continue
        else:
            (a, b) = recta(x1, y1, x2, y2)
        x = i*(x2 - x1)/1000 + x1
        y = a*x + b
        puntos.append((x,y))
        x1 += (xb - xa)/1000
        y1 = a1*x1 + b1
        x2 += (xc - xb)/1000
        y2 = a2*x2 + b2
    return puntos

然后,仅在某些起点,中点和终点运行函数,并使用matplotlib:

lista1 = curva_b(1, 2, 2, 1, 3, 2.5)
lista2 = curva_b(1, 2, 2.5, 1.5, 3, 2.5)
lista3 = curva_b(1, 2, 2.5, 2, 3, 2.5)
lista4 = curva_b(1, 2, 1.5, 3, 3, 2.5)

fig, ax = plt.subplots()
ax.scatter(*zip(*lista1), s=1, c='b')
ax.scatter(*zip(*lista2), s=1, c='r')
ax.scatter(*zip(*lista3), s=1, c='g')
ax.scatter(*zip(*lista4), s=1, c='k')

这应该是结果:

several Bezier quadratic curves

通过再扩展一些代码,可以获得如下形式:

Bezier quartic curve