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

使用Matplotlib与Pandas绘制填充图时fill_between函数异常求助

累计收益填充折线图异常问题解决

问题背景

从SQLite数据库读取交易收益数据,经Pandas计算累计收益后,使用Matplotlib的fill_between函数绘制填充折线图时,出现填充效果与折线不成比例的异常情况。

原代码

import sqlite3 as sql
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 连接数据库
conn = sql.connect(r"C:\Users\lenovo\tradstory.db")
query = "SELECT dates,profit FROM historique"
data = pd.read_sql(query, conn,index_col="dates",parse_dates=True)
data['cumulative_profit'] = data['profit'].cumsum()
initial_balance=9500
# 删除第一行
data = data.iloc[1:]
print(data)

data["cumulative_profit"].plot(figsize=(9,6))

plt.fill_between(data.index,initial_balance, data['cumulative_profit'], alpha=0.2, color='skyblue')
plt.show()

处理后的数据示例

profit  cumulative_profit
dates                                
2023-06-03    0.00           10000.00
2023-06-03    0.00           10000.00
2023-06-03    0.41           10000.41
2023-06-03   -2.31            9998.10
2023-06-03    0.00            9998.10
...            ...                ...
2023-06-17 -443.20           12831.67
2023-06-19    0.00           12831.67
2023-06-19 -811.75           12019.92
2023-06-26    0.00           12019.92
2023-06-26    0.00           12019.92 

问题原因

  • 累计收益计算逻辑错误:设置的初始本金initial_balance=9500,但数据中累计收益从10000开始,说明cumsum()未加入初始本金,导致填充基准线和折线起始值不匹配。
  • 重复日期数据干扰:同一日期存在多条记录,fill_between处理重复索引时易出现渲染异常,导致填充区域比例失调。
  • 绘图函数混用导致坐标轴对齐问题:Pandas的plot()和Matplotlib原生fill_between混用,可能出现坐标轴不一致的情况。

修正方案

修正后的代码

import sqlite3 as sql
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 连接数据库
conn = sql.connect(r"C:\Users\lenovo\tradstory.db")
query = "SELECT dates,profit FROM historique"
data = pd.read_sql(query, conn, index_col="dates", parse_dates=True)

# 修正累计收益计算:初始本金加利润累计
initial_balance = 9500
data['cumulative_profit'] = initial_balance + data['profit'].cumsum()

# 删除第一行(按需保留)
data = data.iloc[1:]

# 处理重复日期:按日期取当日最后一条累计收益(可根据需求调整聚合方式)
data_daily = data.groupby(data.index.date).last().set_index(pd.to_datetime(data.groupby(data.index.date).last().index))

# 创建统一的绘图坐标轴
fig, ax = plt.subplots(figsize=(9,6))

# 绘制累计收益折线
ax.plot(data_daily.index, data_daily['cumulative_profit'], color='blue')

# 绘制填充区域,确保x轴与折线完全对应
ax.fill_between(data_daily.index, initial_balance, data_daily['cumulative_profit'], alpha=0.2, color='skyblue')

# 添加图表标签与标题
ax.set_xlabel('日期')
ax.set_ylabel('累计收益')
ax.set_title('累计收益变化趋势')

# 优化日期显示
plt.xticks(rotation=45)
plt.tight_layout()

plt.show()

关键修正点说明

  1. 修正累计收益计算:将初始本金加入累计收益,确保折线从initial_balance开始增长/减少,与填充基准线一致。
  2. 去重日期数据:按日期聚合数据,避免同一日期多条记录导致的渲染混乱。
  3. 统一绘图流程:使用Matplotlib原生的plt.subplots()创建坐标轴,保证折线和填充区域使用同一坐标轴,解决对齐问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:41:58