Если вы хотите, чтобы построить свои маркера перехвата с использованием произвольных данных (независимо от ваших функций и вертикальных линий может быть) Я бы посоветовал вам вычислить точки пересечения (где они существуют). Несколько месяцев назад я дал ответ, который может быть вам полезен. Вы можете проверить его here.
Приспосабливая подобное решение проблемы:
import numpy as np
import matplotlib.pyplot as plt
def line_intersection(line1, line2):
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1]) #Typo was here
def det(a, b):
return a[0] * b[1] - a[1] * b[0]
div = det(xdiff, ydiff)
if div == 0:
return None
d = (det(*line1), det(*line2))
x = det(d, xdiff)/div
y = det(d, ydiff)/div
return x, y
def near(a, b, rtol=1e-5, atol=1e-8):
return abs(a - b) < (atol + rtol * abs(b))
def crosses(line1, line2):
"""
Return True if line segment line1 intersects line segment line2 and
line1 and line2 are not parallel.
"""
(x1,y1), (x2,y2) = line1
(u1,v1), (u2,v2) = line2
(a,b), (c,d) = (x2-x1, u1-u2), (y2-y1, v1-v2)
e, f = u1-x1, v1-y1
denom = float(a*d - b*c)
if near(denom, 0):
# parallel
return False
else:
t = (e*d - b*f)/denom
s = (a*f - e*c)/denom
# When 0<=t<=1 and 0<=s<=1 the point of intersection occurs within the
# line segments
return 0<=t<=1 and 0<=s<=1
for Fs in np.linspace(70e3,200e3,4):
Vo_sweep = np.linspace(0,1,1000)
delta_I = [i*Fs*np.log((i+1.1)/10) for i in range(len(Vo_sweep))] #[I_max(Vo) for Vo in Vo_sweep]
plt.plot(Vo_sweep,delta_I)
plt.vlines(0.71,min(delta_I),max(delta_I))
for Fs in np.linspace(70e3,200e3,4):
x = np.linspace(0,1,1000)
y = [i*Fs*np.log((i+1.1)/10) for i in range(len(Vo_sweep))]
for i in range(1,len(delta_I)):
p1 = np.array([x[i-1],y[i-1]],dtype='float')
p2 = np.array([x[i],y[i]],dtype='float')
k1 = np.array([0.71,min(delta_I)],dtype='float')
k2 = np.array([0.71,max(delta_I)],dtype='float')
if crosses((p2,p1),(k1,k2)):
seg = line_intersection((p2,p1),(k1,k2))
plt.scatter(seg[0],seg[1],c='red',s=90)
print(seg)
plt.ylim(min(delta_I),max(delta_I))
plt.xlim(0,1)
plt.show()
, что приводит к так:
Этот рецепт также печать перехват координат, если это может представлять интерес для вы:
(0.70999999999999985, 211670610.06954533)
(0.70999999999999985, 342704797.25546497)
(0.70999999999999985, 473738984.44138455)
(0.70999999999999985, 604773171.62730408)
Sin потому что вы не предоставили данные, которые мне пришлось сделать быстро синтетическими, но это должно быть так же просто, как замена вашей функцией I_max()
в определении delta_I
.
Это может быть глупый вопрос, но если ваша ось х имеет целые значения от 0 до 1000 (что вы как-то рисуете от 0 до 1.0), это не значение y 'x = 0.71'just' I_max (709) '? Затем вы можете использовать аннотацию (например), чтобы записать это значение в график. См. Здесь: http://matplotlib.org/users/annotations_intro.html – StefanS
Я согласен с @StefanS. По построению вы уже знаете значение каждой функции при x = 0.71 или ближайшем x к этому. Итак, моим предложением было бы сохранить I_max (0.71) в списке, а затем добавить небольшую панель ниже, которая показывает I_max (0.71) как функцию частоты. Если у вас много разных кривых, это даст вам спокойную гладкую функцию, которую можно легко понять. – Alejandro