使用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()
关键修正点说明
- 修正累计收益计算:将初始本金加入累计收益,确保折线从
initial_balance开始增长/减少,与填充基准线一致。 - 去重日期数据:按日期聚合数据,避免同一日期多条记录导致的渲染混乱。
- 统一绘图流程:使用Matplotlib原生的
plt.subplots()创建坐标轴,保证折线和填充区域使用同一坐标轴,解决对齐问题。
内容的提问来源于stack exchange,提问作者Josue Komi
相关产品推荐
相关产品推荐

