如何在Python3的mplfinance日本蜡烛图中添加涨跌幅百分比框?
解决mplfinance添加涨跌幅百分比框的TypeError问题
报错核心原因
你碰到的TypeError: must be real number, not Timestamp,是因为绘制涨跌幅框时错误地把时间轴的Timestamp对象当成数值坐标传入了绘图函数。mplfinance底层绘图需要的是数值化的x轴位置(比如DataFrame的行索引序号),而非原始时间戳对象。
实现步骤与代码修改
1. 先完成涨跌幅核心计算
先确定起始蜡烛的开盘价,再统计后续K线的高低价,算出涨跌幅百分比:
import mplfinance as mpf import pandas as pd import matplotlib.pyplot as plt # 假设你的数据已整理为带DatetimeIndex的DataFrame,命名为df # 指定起始K线的位置(比如第0根,或根据需求调整) start_idx = 0 start_open = df.iloc[start_idx]['Open'] # 计算起始K线之后的最高、最低价 max_high = df.iloc[start_idx:]['High'].max() min_low = df.iloc[start_idx:]['Low'].min() # 计算涨跌幅百分比 up_pct = (max_high - start_open) / start_open * 100 down_pct = (min_low - start_open) / start_open * 100
2. 绘制蜡烛图并添加涨跌幅框
通过returnfig=True获取绘图对象,手动绘制矩形框,避免Timestamp错误:
# 绘制基础蜡烛图,获取画布和轴对象 fig, axes = mpf.plot(df, type='candle', returnfig=True, figsize=(12, 8)) # 确定x轴的数值化位置:用行索引序号而非时间戳 x_start = start_idx x_end = len(df) - 1 # 计算涨跌幅对应的价格边界 price_up = start_open * (1 + up_pct / 100) price_down = start_open * (1 + down_pct / 100) # 添加涨跌幅矩形框 axes[0].add_patch( plt.Rectangle( (x_start, price_down), # 矩形左下角坐标 x_end - x_start, # 矩形宽度 price_up - price_down, # 矩形高度 fill=False, edgecolor='darkred', linestyle='--', linewidth=1.5 ) ) # 添加涨跌幅文本标注 axes[0].text(x_end, price_up, f'+{up_pct:.2f}%', color='green', va='bottom', fontsize=9) axes[0].text(x_end, price_down, f'{down_pct:.2f}%', color='red', va='top', fontsize=9) # 显示图形 mpf.show()
3. 关键注意事项
- 禁止直接使用
df.index[start_idx](Timestamp对象)作为x坐标,必须用DataFrame的整数行索引。 - 如果需要按指定时间筛选起始K线,先把时间转为索引序号:
start_time = pd.Timestamp('2023-01-01') start_idx = df.index.get_loc(start_time) - 确保DataFrame的索引是无重复的DatetimeIndex,否则
get_loc会报错。
4. 批量绘制优化(可选)
如果需要给多段K线添加涨跌幅框,可以封装成函数循环调用:
def add_pct_box(ax, df, start_idx, edge_color='darkred'): start_open = df.iloc[start_idx]['Open'] max_high = df.iloc[start_idx:]['High'].max() min_low = df.iloc[start_idx:]['Low'].min() up_pct = (max_high - start_open)/start_open*100 down_pct = (min_low - start_open)/start_open*100 x_start = start_idx x_end = len(df)-1 price_up = start_open*(1+up_pct/100) price_down = start_open*(1+down_pct/100) ax.add_patch(plt.Rectangle((x_start, price_down), x_end-x_start, price_up-price_down, fill=False, edgecolor=edge_color, linestyle='--')) ax.text(x_end, price_up, f'+{up_pct:.2f}%', color='green', va='bottom', fontsize=9) ax.text(x_end, price_down, f'{down_pct:.2f}%', color='red', va='top', fontsize=9) # 使用示例:给第5根和第20根K线添加涨跌幅框 fig, axes = mpf.plot(df, type='candle', returnfig=True) add_pct_box(axes[0], df, 5) add_pct_box(axes[0], df, 20, edge_color='darkblue') mpf.show()
内容的提问来源于stack exchange,提问作者NoahVerner
相关产品推荐
相关产品推荐

