Matplotlib添加第二个累积收益曲线时压扁第一个收盘价曲线如何解决
问题原因
- 两个曲线的数值量级差异过大:你计算的
return是相邻时间段收盘价的比值,正常在1附近波动,但是return_cum是该比值的累计和,随数据行数增加会持续累加,数值会远大于1,乘以收盘价后得到的test数值量级会比原始close高几十到上百倍。 - Matplotlib默认会自动适配y轴范围到所有序列的最大最小值,所以y轴被量级大的
test序列占满,数值小的close波动就会被压缩到接近一条直线,就是你看到的“压扁”效果。
修复方案
你可以根据自己的分析需求选择以下任意一种方案:
方案1:使用双Y轴(推荐,保留原始数值)
两个曲线分别绑定左右两个独立的Y轴,互不影响数值量级适配:
import pandas as pd import matplotlib.pyplot as plt dfin = pd.read_csv(inputfilename, sep=";", encoding='ISO-8859-1') # create a return column dfin['return'] = dfin['close'].shift(9) / dfin['close'].shift(12) # create a cumulative sum column dfin['return_cum'] = dfin['return'].cumsum() close = dfin.iloc[:-1]['close'] test = dfin.iloc[:-1]['close'] * dfin.iloc[:-1]['return_cum'] fig, ax1 = plt.subplots(figsize=(20, 10)) # 左侧Y轴绘制收盘价 ax1.plot(close, color='black', label='收盘价') ax1.set_ylabel('收盘价', color='black') ax1.tick_params(axis='y', labelcolor='black') # 右侧Y轴绘制累计收益指标 ax2 = ax1.twinx() ax2.plot(test, color='blue', label='累计收益相关指标') ax2.set_ylabel('累计收益指标', color='blue') ax2.tick_params(axis='y', labelcolor='blue') # 合并显示图例 fig.legend(loc="upper right", bbox_to_anchor=(1,1), bbox_transform=ax1.transAxes) plt.show() plt.close()
方案2:数据归一化(适合对比趋势)
将两个序列都缩放到相同的基准区间,就可以在同一个Y轴展示:
close = dfin.iloc[:-1]['close'] test = dfin.iloc[:-1]['close'] * dfin.iloc[:-1]['return_cum'] # 以序列第一个有效值为基准做归一化,统一缩放到1为起点 close_norm = close / close.dropna().iloc[0] test_norm = test / test.dropna().iloc[0] fig, axs = plt.subplots(figsize=(20, 10)) axs.plot(close_norm, color='black', label='收盘价(归一化)') axs.plot(test_norm, color='blue', label='累计收益指标(归一化)') axs.legend() plt.show() plt.close()
方案3:修正累计收益计算逻辑(优先检查)
常规的累计收益计算不是对比值做cumsum,如果是计算逻辑错误导致数值量级异常,可以先修正计算逻辑,修正后test的量级和close接近,就可以直接同轴绘制:
# 修正为复利累计收益,数值始终在1附近波动 dfin['return_cum'] = dfin['return'].cumprod() # 或者修正为简单累计收益率 # dfin['return_cum'] = 1 + (dfin['return'] - 1).cumsum() test = dfin.iloc[:-1]['close'] * dfin.iloc[:-1]['return_cum'] # 后续绘图逻辑和初始代码一致即可
内容的提问来源于stack exchange,提问作者John Bailey
相关产品推荐
相关产品推荐

