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

使用Tiingo API绘制股票散点图时遇TypeError问题求助

问题分析与解决

问题背景

使用Tiingo API获取4只股票(TSLA、ADDYY、UPS、PFE)2020-2021年数据后,成功绘制了4个独立的日涨跌幅直方图,但运行散点图代码时触发TypeError: no numerical data to plot错误,期望得到对应4只股票的独立散点图。

可正常运行的直方图代码

import datetime
import pandas_datareader as pdr 
import pandas as pd

api_key='thisisasecret'
tickers = ['TSLA', 'ADDYY', 'UPS', 'PFE']
start="2020-1-1"
end="2021-7-1"

df = pdr.tiingo.TiingoDailyReader(tickers, start=start, end=end, api_key=api_key)
all_data = df.read()
all_data

import matplotlib.pyplot as plt

daily_close_px = all_data[['adjClose']].reset_index().pivot('date', 'symbol', 'adjClose')
daily_pct_change = daily_close_px.pct_change()
daily_pct_change.hist(bins=50, sharex=True, figsize=(12,8))

plt.show()

报错的散点图代码

all_data.plot(kind='scatter',x='date',y='adjClose')
plt.title('Stock Scatter Analysis')
plt.xlabel('date')
plt.ylabel('closing price')

plt.show()

错误原因

  1. 索引与列的混淆:Tiingo返回的all_data是多层索引(MultiIndex),date和symbol属于索引层级,不是普通数据列。plot.scatter要求x参数指定的是数值型数据列,直接传入'date'会导致pandas无法找到对应数值数据。
  2. 数据结构不匹配:直方图代码中通过pivot将数据整理成了每列对应一只股票的宽表结构,pandas的hist方法能自动为每列生成子图;但原始all_data是包含所有股票的长表,直接调用plot.scatter无法自动拆分生成多子图,且date为datetime类型不符合散点图的数值要求。

解决方法

方法1:基于透视后的宽表绘制(推荐)

复用直方图中已经处理好的daily_close_px宽表,手动创建子图并绘制:

import matplotlib.pyplot as plt

# 创建2x2子图布局
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

# 遍历每只股票绘制散点图
for idx, ticker in enumerate(daily_close_px.columns):
    # 将datetime类型的日期转为秒级时间戳(数值型)
    x_timestamp = daily_close_px.index.astype('int64') // 10**9
    axes[idx].scatter(x_timestamp, daily_close_px[ticker])
    axes[idx].set_title(f'{ticker} 调整收盘价 vs 日期')
    axes[idx].set_ylabel('调整收盘价')
    # 将x轴时间戳格式化为日期显示
    axes[idx].xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m'))
    axes[idx].tick_params(axis='x', rotation=45)

plt.tight_layout()
plt.show()

方法2:直接处理原始长表数据

如果不想依赖透视后的宽表,可先重置索引拆分数据再绘制:

import matplotlib.pyplot as plt

# 重置索引,将date和symbol转为普通列
all_data_reset = all_data.reset_index()

# 创建2x2子图布局
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

# 按股票分组绘制
for idx, (ticker, group) in enumerate(all_data_reset.groupby('symbol')):
    # 日期转时间戳
    x_timestamp = group['date'].astype('int64') // 10**9
    axes[idx].scatter(x_timestamp, group['adjClose'])
    axes[idx].set_title(f'{ticker} 调整收盘价 vs 日期')
    axes[idx].set_ylabel('调整收盘价')
    # 格式化x轴日期
    axes[idx].xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m'))
    axes[idx].tick_params(axis='x', rotation=45)

plt.tight_layout()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:30:46