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

使用Matplotlib合并CALL与PUT的CDF图并添加百分位竖线遇问题

问题解决:合并CALL/PUT的CDF柱状图并正确添加百分位竖线

问题背景

已成功单独绘制CALL和PUT未平仓量的CDF柱状图,且每张图都能正确添加40%、80%百分位的竖线,但合并两张图时,生成的图表混乱,竖线位置完全错误。

核心问题分析

  1. 竖线位置匹配错误:单图绘制时用原DataFrame的索引作为x轴位置,但合并后用sns.barplot时,x轴是按Strike的唯一值重新排序后的位置,原索引和新x轴位置不对应,导致竖线画错地方。
  2. 数据合并后的结构问题:直接concat两张DataFrame,未确保Strike对齐,可能导致柱状图错位或重复。

修正方案与代码

步骤1:确保数据对齐

先让CALL和PUT的DataFrame按Strike列对齐,保证每个Strike同时包含CALL和PUT的CDF数据:

# 按Strike合并CALL和PUT数据,保留双方的CDF和Percentile
merged_df = pd.merge(CALL[['STRIKE', 'CDF', 'Percentile']], 
                     PUT[['STRIKE', 'CDF', 'Percentile']], 
                     on='STRIKE', 
                     suffixes=('_call', '_put'))
# 转换为适合seaborn长格式的数据
long_df = merged_df.melt(id_vars='STRIKE', 
                         value_vars=['CDF_call', 'CDF_put'], 
                         var_name='Type', 
                         value_name='CDF')
long_df['Type'] = long_df['Type'].map({'CDF_call': 'CALL', 'CDF_put': 'PUT'})

步骤2:正确计算竖线位置

绘图时,先获取sns.barplot生成的x轴刻度对应的Strike值,再找到目标Strike在x轴上的位置:

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(16, 6))
# 绘制双柱状图,每个Strike对应CALL和PUT两个柱子
ax = sns.barplot(x='STRIKE', y='CDF', hue='Type', data=long_df, 
                 palette={'CALL': 'lightgreen', 'PUT': 'orange'})

# ---------------------- 处理CALL的百分位竖线 ----------------------
# 找到CALL的40%、80%最近的Strike
call_40_strike = CALL.loc[(CALL['Percentile'] - 0.4).abs().idxmin(), 'STRIKE']
call_80_strike = CALL.loc[(CALL['Percentile'] - 0.8).abs().idxmin(), 'STRIKE']
# 获取x轴刻度对应的Strike列表
x_ticks = [tick.get_text() for tick in ax.get_xticklabels()]
# 找到目标Strike在x轴上的位置(注意转换为相同类型,比如字符串)
call_40_pos = x_ticks.index(str(call_40_strike))
call_80_pos = x_ticks.index(str(call_80_strike))
# 添加竖线,双柱状图每个Strike占两个位置,调整位置让线落在对应柱子中心
ax.axvline(x=call_40_pos + 0.25, color='red', linestyle='--', label=f'CALL 40% ({call_40_strike})')
ax.axvline(x=call_80_pos + 0.25, color='darkred', linestyle='--', label=f'CALL 80% ({call_80_strike})')

# ---------------------- 处理PUT的百分位竖线 ----------------------
put_40_strike = PUT.loc[(PUT['Percentile'] - 0.4).abs().idxmin(), 'STRIKE']
put_80_strike = PUT.loc[(PUT['Percentile'] - 0.8).abs().idxmin(), 'STRIKE']
put_40_pos = x_ticks.index(str(put_40_strike))
put_80_pos = x_ticks.index(str(put_80_strike))
ax.axvline(x=put_40_pos - 0.25, color='blue', linestyle='--', label=f'PUT 40% ({put_40_strike})')
ax.axvline(x=put_80_pos - 0.25, color='darkblue', linestyle='--', label=f'PUT 80% ({put_80_strike})')

# 设置图表样式
plt.xlabel('STRIKE')
plt.ylabel('Cumulative Distribution Function (CDF)')
plt.title('CDF for CALL and PUT Open Interest')
plt.xticks(rotation=60)
plt.legend()
plt.grid(axis='y')
plt.tight_layout()
plt.show()

关键修正点

  • 改用pd.merge对齐Strike,确保每个Strike都有CALL和PUT的数据,避免柱状图错位。
  • 转换为长格式数据适配seaborn的hue参数,生成双柱状图更清晰。
  • 通过ax.get_xticklabels()获取实际x轴的Strike标签,计算竖线的正确位置,解决原索引不匹配的问题。
  • 双柱状图中,每个Strike对应两个柱子,通过±0.25调整竖线位置,让线落在对应类型柱子的中心区域。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:35:07