2015-04-27 16 views
10

Tôi có dữ liệu được trình bày trong hình.Cách tìm điểm giao nhau của đường và nhiều đường cong bằng Python?

enter image description here

Các đường cong được ngoại suy và tôi có một dòng có phương trình được biết đến. Phương trình đường cong không xác định. Bây giờ, làm cách nào để tôi tìm ra điểm giao nhau của đường này với mỗi đường cong?

Mã tái sản xuất:

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


x = np.array([[0.12, 0.11, 0.1, 0.09, 0.08], 
       [0.13, 0.12, 0.11, 0.1, 0.09], 
       [0.15, 0.14, 0.12, 0.11, 0.1], 
       [0.17, 0.15, 0.14, 0.12, 0.11], 
       [0.19, 0.17, 0.16, 0.14, 0.12], 
       [0.22, 0.19, 0.17, 0.15, 0.13], 
       [0.24, 0.22, 0.19, 0.16, 0.14], 
       [0.27, 0.24, 0.21, 0.18, 0.15], 
       [0.29, 0.26, 0.22, 0.19, 0.16]]) 

y = np.array([[71.64, 78.52, 84.91, 89.35, 97.58], 
       [66.28, 73.67, 79.87, 85.36, 93.24], 
       [61.48, 69.31, 75.36, 81.87, 89.35], 
       [57.61, 65.75, 71.7, 79.1, 86.13], 
       [55.12, 63.34, 69.32, 77.29, 83.88], 
       [54.58, 62.54, 68.7, 76.72, 82.92], 
       [56.58, 63.87, 70.3, 77.69, 83.53], 
       [61.67, 67.79, 74.41, 80.43, 85.86], 
       [70.08, 74.62, 80.93, 85.06, 89.84]]) 


x1 = np.linspace(0, 0.4, 100) 
y1 = -100 * x1 + 100 
plt.figure(figsize = (5.15,5.15)) 
plt.subplot(111) 
for i in range(5): 
    x_val = np.linspace(x[0, i] - 0.05, x[-1, i] + 0.05, 100) 
    x_int = np.interp(x_val, x[:, i], y[:, i]) 
    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') 
plt.plot(x1, y1, linestyle = '-.', linewidth = 0.5, color = 'black') 


plt.xlabel('X') 
plt.ylabel('Y') 
plt.show() 

Trả lời

16

Chúng tôi làm biết các phương trình của các đường cong. Chúng có dạng a*x**2 + b*x + c, trong đó a, bc là các phần tử của véc tơ được trả về bởi np.polyfit. Sau đó, chúng ta chỉ cần tìm ra gốc rễ của một phương trình bậc hai để tìm ra các nút giao thông:

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 

Chức năng ở trên không phải là siêu mạnh mẽ: có không cần là một gốc thực, và nó không thực sự kiểm tra điều đó. Bạn được tự do để làm cho nó tốt hơn.

Dù sao, chúng tôi cung cấp quadratic_intersections hai quadratics và trả về hai điểm giao nhau. Đưa nó vào mã của bạn, chúng ta có:

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() 

Điều này làm cho hình sau:

enter image description here

Bây giờ, nếu bạn không biết rằng các chức năng bạn đang đối phó với những đa thức, bạn có thể sử dụng các công cụ tối ưu hóa trong scipy.optimize để tìm gốc. Ví dụ:

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]) 

Những lô:

enter image description here

+0

này là rất tốt, nhưng trong trường hợp tôi có một chức năng không rõ, có thể làm gì? –

+2

bạn có thể chia sẻ tệp cấu hình mpl của mình không? Tôi thấy âm mưu này rất đẹp ^^ – astrojuanlu

+0

Có thể tốt hơn để trả về các mảng tọa độ riêng biệt từ 'quadratic_intersections', ví dụ' x = np.roots (np.asarray (p) - q); y = np.polyval (p, x); return x, y'. –

Các vấn đề liên quan