首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在一个散射点上绘制2条趋势线?(python)

如何在一个散射点上绘制2条趋势线?(python)
EN

Stack Overflow用户
提问于 2021-07-27 21:36:06
回答 1查看 407关注 0票数 1

我想用中的Matplotlib绘制的1散点图,但我不知道如何绘制。图形应该类似于这个https://www.ncbi.nlm.nih.gov/core/lw/2.0/html/tileshop_pmc/tileshop_pmc_inline.html?title=Click%20on%20image%20to%20zoom&p=PMC3&id=3438148_MJMS-11-1-024-g2.jpg (来自这里,图2)。

我设法在散点图这里上绘制了1条趋势线,但不知道如何绘制另一种趋势。

下面是我尝试过的:

对于我所绘制的其他参数,这被证明是可以的,但对于这个例子,这使我得出结论,这并不是太正确。

代码语言:javascript
复制
X = vO2.reshape(-1, 1)
Y = ve.reshape(-1, 1)
linear_regressor = LinearRegression()
linear_regressor.fit(X, Y)
y_pred = linear_regressor.predict(X)
x_pred = linear_regressor.predict(Y)

plt.scatter(X, Y)
plt.plot(X, y_pred, '-*',label="O2")
plt.plot(x_pred, Y, '-*',label="vent")
plt.xlabel("VO2 (L/min)")
plt.ylabel("VE (L/min)")
plt.show()

而且还

代码语言:javascript
复制
z1 = np.polyfit(vO2, ve, 1)
p1 = np.poly1d(z1)

z2 = np.polyfit(ve, vO2, 1)
p2 = np.poly1d(z2)

plt.scatter(vO2, ref_vent, label='original')
plt.plot(vO2, p1(vO2), label='trendline')
plt.plot(ve, p2(ve), label='trendline')
plt.show()

看上去也不像目标情节。

我不知道怎么继续。提前感谢!

vo2 = 1.673925 1.9015125 1.981775 2.112875 2.1112625 2.13475 2.1777 2.1857125 2.258925 2.2718375 2.3330875 2.353725 2.4879625 2.448275 2.48875 2.5084375 2.5084375 2.5511 2.5678375 2.5844675 2.6457375 2.6457375 2.6602125 2.6939875 2.710625 2.710675 2.767025 2.752.776025 2.7375 2.776025 2.7375 2.77775 2.776025 2.7375 2.429625 2.42965 2.387175 2.3544375

ve = 3.93125 7.1975 9.04375 14.06125 14.11875 13.24375 14.6625 15.3625 15.2 15.035 17.7625 17.955 19.2675 19.875 19.1575 21.1575 23.75625 23.30875 25.9925 25.6775 27.33875 27.7775 27.9625 29.35 31.86125 32.2425 33.7575 34.69125 36.20125 38.6325 39.4425 42.085 45.17 47.18 42.295 37.5125 38.84375 37.4775 34.20375 33.18 32.67708333

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-28 00:33:59

好的,所以你需要找到点,在那里的斜率变化的线。我尝试了二阶导数,但是它很吵,我找不到合适的位置。

另一种方法是尝试所有可能的点,计算左、右回归线,并找到最适合的对(r2 coeff)。试试看这段代码。这是不完整的。我不知道,如何迫使回归线在中间通过点。如果没有足够的数据点,使用内插数据可能会更好。

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score


vo2 = [1.673925,1.9015125,1.981775,2.112875,2.1112625,2.086375,2.13475,2.1777,2.176975,2.1857125,2.258925,2.2718375,2.3381,2.3330875,2.353725,2.4879625,2.448275,2.4829875,2.5084375,2.511275,2.5511,2.5678375,2.5844625,2.6101875,2.6457375,2.6602125,2.6939875,2.7210625,2.720475,2.767025,2.751375,2.7771875,2.776025,2.7319875,2.564,2.3977625,2.4459125,2.42965,2.401275,2.387175,2.3544375]

ve = [ 3.93125,7.1975,9.04375,14.06125,14.11875,13.24375,14.6625,15.3625,15.2,15.035,17.7625,17.955,19.2675,19.875,21.1575,22.9825,23.75625,23.30875,25.9925,25.6775,27.33875,27.7775,27.9625,29.35,31.86125,32.2425,33.7575,34.69125,36.20125,38.6325,39.4425,42.085,45.17,47.18,42.295,37.5125,38.84375,37.4775,34.20375,33.18,32.67708333]

x = np.array(vo2)
y = np.array(ve)

sort_idx = x.argsort()
x = x[sort_idx]
y = y[sort_idx]

assert len(x) == len(y)

def fit(x,y):
    p = np.polyfit(x, y, 1)
    f = np.poly1d(p)
    r2 = r2_score(y, f(x))
    return p, f, r2

skip = 5  # minimal length of split data
r2 = [0] * len(x)  
funcs = {}

for i in range(len(x)):
    if i < skip or i > len(x) - skip:
        continue

    _, f_left, r2_left = fit(x[:i], y[:i])
    _, f_right, r2_right = fit(x[i:], y[i:])

    r2[i] = r2_left * r2_right
    funcs[i] = (f_left, f_right)
    
split_ix = np.argmax(r2)  # index of split
f_left,f_right = funcs[split_ix]   
  
print(f"split point index: {split_ix}, x: {x[split_ix]}, y: {y[split_ix]}")  
  
    
xd = np.linspace(min(x), max(x), 100)
plt.plot(x, y, "o")
plt.plot(xd, f_left(xd))
plt.plot(xd, f_right(xd))
plt.plot(x[split_ix], y[split_ix], "x")
plt.show()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68552018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档