更新 1:
现在 Plotly Express 能够轻松处理长格式和宽格式(后者是你的情况)的数据,绘制回归线所需的唯一步骤是:
fig = px.scatter(df, x='X', y='Y', trendline="ols")
完整的代码片段位于问题末尾的宽数据处。
![enter image description here](https://istack.dev59.com/icQhR.webp)
如果您希望回归线更加明显,您可以在以下位置指定
trendline_color_override
:
fig = `px.scatter([...], trendline_color_override = 'red')
或者在通过以下方式构建图形后包含线条颜色:
fig.data[1].line.color = 'red'
![enter image description here](https://istack.dev59.com/mcghE.webp)
你可以通过以下方式访问回归参数
alpha
和
beta
:
model = px.get_trendline_results(fig)
alpha = model.iloc[0]["px_fit_results"].params[0]
beta = model.iloc[0]["px_fit_results"].params[1]
你甚至可以通过以下方式请求非线性拟合:
fig = px.scatter(df, x='X', y='Y', trendline="lowess")
![enter image description here](https://istack.dev59.com/8AFdq.webp)
而那些长格式怎么办?这就是Plotly Express展现其真正实力的地方。以内置数据集
px.data.gapminder
为例,您可以通过指定
color="continent"
来触发一系列国家的单独线条:
![enter image description here](https://istack.dev59.com/nL34U.webp)
完整的长格式片段
import plotly.express as px
df = px.data.gapminder().query("year == 2007")
fig = px.scatter(df, x="gdpPercap", y="lifeExp", color="continent", trendline="lowess")
fig.show()
如果您希望在模型选择和输出方面拥有更大的灵活性,您可以随时参考下面我对此帖子的原始回答。但首先,这里是我更新后的答案开头的完整代码片段:
宽数据的完整代码片段
import plotly.graph_objects as go
import plotly.express as px
import statsmodels.api as sm
import pandas as pd
import numpy as np
import datetime
np.random.seed(123)
numdays=20
X = (np.random.randint(low=-20, high=20, size=numdays).cumsum()+100).tolist()
Y = (np.random.randint(low=-20, high=20, size=numdays).cumsum()+100).tolist()
df = pd.DataFrame({'X': X, 'Y':Y})
fig = px.scatter(df, x='X', y='Y', trendline="lowess")
fig.data[1].line.color = 'red'
fig.update_layout(xaxis_title = 'X', yaxis_title = 'Y')
fig.show()
原始回答:
对于回归分析,我喜欢使用statsmodels.api
或sklearn.linear_model
。我还喜欢将数据和回归结果组织在pandas dataframe中。以下是一种以清晰有序的方式完成您所需内容的方法:
使用sklearn或statsmodels进行绘图:
![enter image description here](https://istack.dev59.com/YOVG9.webp)
使用sklearn的代码:
from sklearn.linear_model import LinearRegression
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import datetime
np.random.seed(123)
numdays=20
X = (np.random.randint(low=-20, high=20, size=numdays).cumsum()+100).tolist()
Y = (np.random.randint(low=-20, high=20, size=numdays).cumsum()+100).tolist()
df = pd.DataFrame({'X': X, 'Y':Y})
reg = LinearRegression().fit(np.vstack(df['X']), Y)
df['bestfit'] = reg.predict(np.vstack(df['X']))
fig=go.Figure()
fig.add_trace(go.Scatter(name='X vs Y', x=df['X'], y=df['Y'].values, mode='markers'))
fig.add_trace(go.Scatter(name='line of best fit', x=X, y=df['bestfit'], mode='lines'))
fig.update_layout(xaxis_title = 'X', yaxis_title = 'Y')
fig.show()
使用 statsmodels 的代码:
import plotly.graph_objects as go
import statsmodels.api as sm
import pandas as pd
import numpy as np
import datetime
np.random.seed(123)
numdays=20
X = (np.random.randint(low=-20, high=20, size=numdays).cumsum()+100).tolist()
Y = (np.random.randint(low=-20, high=20, size=numdays).cumsum()+100).tolist()
df = pd.DataFrame({'X': X, 'Y':Y})
df['bestfit'] = sm.OLS(df['Y'],sm.add_constant(df['X'])).fit().fittedvalues
fig=go.Figure()
fig.add_trace(go.Scatter(name='X vs Y', x=df['X'], y=df['Y'].values, mode='markers'))
fig.add_trace(go.Scatter(name='line of best fit', x=X, y=df['bestfit'], mode='lines'))
fig.update_layout(xaxis_title = 'X', yaxis_title = 'Y')
fig.show()