如何批量生成并排散点图并添加最佳拟合线?子图尝试失败求助
股票与SPY指数散点图批量绘制及拟合线添加方案
我已经掌握单独绘制散点图的方法,现在需要实现:
- 编写循环逻辑,将JPM、C、BAC、MS、GS、WFC、BCS这7只股票分别与SPY指数对比的散点图并排展示在同一视图中
- 每个散点图添加最佳拟合线以呈现回归关系
此前尝试通过数组创建子图但未成功,现有Python代码如下:
import yfinance as yf, matplotlib.pyplot as plt, numpy as np import pandas_datareader.data as reader import statsmodels.api as sm import seaborn as sns import pandas as pd from scipy import stats from dateutil.relativedelta import * import getFamaFrenchFactors as gff import datetime from sklearn.linear_model import LinearRegression import pandas as pd from xbbg import blp tickers = ['JPM', 'C', 'BAC', 'MS', 'GS', 'WFC', 'BCS'] weights = np.array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) today1= datetime.date.today() olddate1 = today1 - datetime.timedelta(weeks=26.5) df_spy = yf.download('SPY', olddate1, today1)['Adj Close'] today= datetime.date.today() olddate = today - datetime.timedelta(weeks=26.5) df = yf.download(tickers, olddate, today)['Adj Close'] fig,ax=plt.subplots(figsize=(10,10), nrows=2, ncols=1, sharex=True) Scatter1=ax[0].scatter(x=df_spy.pct_change(), y = df[tickers[0]].pct_change(), c=) plt.rcParams['axes.grid'] = False plt.scatter(df_spy.pct_change(),df[tickers[0]].pct_change(), alpha =.6, color='blue', s=55) plt.scatter(df_spy.pct_change(),df[tickers[1]].pct_change(), alpha =.6, color='blue', s=55) plt.scatter(df_spy.pct_change(),df[tickers[2]].pct_change(), alpha =.6, color='blue', s=55) plt.scatter(df_spy.pct_change(),df[tickers[3]].pct_change(), alpha =.6, color='blue', s=55) plt.scatter(df_spy.pct_change(),df[tickers[4]].pct_change(), alpha =.6, color='blue', s=55) plt.scatter(df_spy.pct_change(),df[tickers[5]].pct_change(), alpha =.6, color='blue', s=55) plt.scatter(df_spy.pct_change(),df[tickers[6]].pct_change(), alpha =.6, color='blue', s=55)
修正后的完整实现代码
import yfinance as yf import matplotlib.pyplot as plt import numpy as np from sklearn.linear_model import LinearRegression import datetime # 目标股票列表与时间范围设置 tickers = ['JPM', 'C', 'BAC', 'MS', 'GS', 'WFC', 'BCS'] today = datetime.date.today() olddate = today - datetime.timedelta(weeks=26.5) # 下载并预处理收益率数据:计算日涨跌幅,删除空值确保数据对齐 df_spy = yf.download('SPY', olddate, today)['Adj Close'].pct_change().dropna() df_stocks = yf.download(tickers, olddate, today)['Adj Close'].pct_change().dropna() # 设置子图布局:3行3列,刚好容纳7个股票对比图 fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(15, 12)) plt.rcParams['axes.grid'] = False # 循环遍历每只股票,批量绘制散点图与拟合线 for idx, ticker in enumerate(tickers): # 计算当前子图的行列位置 row = idx // 3 col = idx % 3 ax = axes[row, col] # 提取回归所需的特征与目标变量 x = df_spy.values.reshape(-1, 1) y = df_stocks[ticker].values # 绘制散点图 ax.scatter(x, y, alpha=0.6, color='steelblue', s=20) # 训练线性回归模型并绘制拟合线 model = LinearRegression() model.fit(x, y) y_pred = model.predict(x) ax.plot(x, y_pred, color='crimson', linewidth=2, label=f'拟合线: y={model.coef_[0]:.3f}x + {model.intercept_:.4f}') # 设置子图标题与坐标轴标签 ax.set_title(f'{ticker} vs SPY', fontsize=10) ax.set_xlabel('SPY 日收益率', fontsize=8) ax.set_ylabel(f'{ticker} 日收益率', fontsize=8) ax.legend(fontsize=8) # 隐藏最后一个空白子图 axes[2, 2].axis('off') # 自动调整子图间距,避免标题、标签重叠 plt.tight_layout() plt.show()
关键改进说明
- 子图布局优化:采用3行3列的布局,完美容纳7个股票对比图,最后一个空白子图直接隐藏
- 数据对齐处理:统一计算日收益率并删除空值,确保SPY与个股数据时间维度完全匹配
- 循环批量逻辑:通过
enumerate遍历股票列表,自动分配子图位置,避免重复代码 - 拟合线标注:在每个子图中直接显示回归方程,清晰展示个股与SPY的线性关系
- 布局细节调整:用
tight_layout()自动调整子图间距,解决标题、标签重叠问题
内容的提问来源于stack exchange,提问作者rocket
相关产品推荐
相关产品推荐

