You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何批量生成并排散点图并添加最佳拟合线?子图尝试失败求助

股票与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()

关键改进说明

  1. 子图布局优化:采用3行3列的布局,完美容纳7个股票对比图,最后一个空白子图直接隐藏
  2. 数据对齐处理:统一计算日收益率并删除空值,确保SPY与个股数据时间维度完全匹配
  3. 循环批量逻辑:通过enumerate遍历股票列表,自动分配子图位置,避免重复代码
  4. 拟合线标注:在每个子图中直接显示回归方程,清晰展示个股与SPY的线性关系
  5. 布局细节调整:用tight_layout()自动调整子图间距,解决标题、标签重叠问题

内容的提问来源于stack exchange,提问作者rocket

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:10:58