Ответ 1
Мы знаем уравнения кривых. Они имеют вид a*x**2 + b*x + c
, где a
, b
и c
- это элементы вектора, возвращаемого np.polyfit
. Тогда нам просто нужно найти корни квадратного уравнения, чтобы найти пересечения:
def quadratic_intersections(p, q):
"""Given two quadratics p and q, determines the points of intersection"""
x = np.roots(np.asarray(p) - np.asarray(q))
y = np.polyval(p, x)
return x, y
Вышеуказанная функция не является супернадежной: нет необходимости в реальном корне, и на самом деле это не проверяется. Вы можете сделать это лучше.
В любом случае мы даем quadratic_intersections
две квадратики и возвращаем две точки пересечения. Введя его в ваш код, мы имеем:
x1 = np.linspace(0, 0.4, 100)
y1 = -100 * x1 + 100
plt.figure(figsize = (7,7))
plt.subplot(111)
plt.plot(x1, y1, linestyle = '-.', linewidth = 0.5, color = 'black')
for i in range(5):
x_val = np.linspace(x[0, i] - 0.05, x[-1, i] + 0.05, 100)
poly = np.polyfit(x[:, i], y[:, i], deg=2)
y_int = np.polyval(poly, x_val)
plt.plot(x[:, i], y[:, i], linestyle = '', marker = 'o')
plt.plot(x_val, y_int, linestyle = ':', linewidth = 0.25, color = 'black')
ix = quadratic_intersections(poly, [0, -100, 100])
plt.scatter(*ix, marker='x', color='black', s=40, linewidth=2)
plt.xlabel('X')
plt.ylabel('Y')
plt.xlim([0,.35])
plt.ylim([40,110])
plt.show()
Это делает следующий рисунок:
Теперь, если вы не знаете, что функции, с которыми вы имеете дело, являются полиномами, вы можете использовать инструменты оптимизации в scipy.optimize найти корень. Например:
import scipy.optimize
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.style
matplotlib.style.use('fivethirtyeight')
%matplotlib inline
f = lambda x: np.cos(x) - x
g = np.sin
h = lambda x: f(x) - g(x)
x = np.linspace(0,3,100)
plt.plot(x, f(x), zorder=1)
plt.plot(x, g(x), zorder=1)
x_int = scipy.optimize.fsolve(h, 1.0)
y_int = f(x_int)
plt.scatter(x_int, y_int, marker='x', s=150, zorder=2,
linewidth=2, color='black')
plt.xlim([0,3])
plt.ylim([-4,2])
Какие графики: