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

Matplotlib实现带键盘箭头步进动画的交互式股票K线图问题求解

问题原因
  • 未清空历史绘图元素:每次按键触发回调时,仅叠加绘制新区间的K线,不会删除之前已绘制的内容,导致旧K线始终留在图上,按左箭头时也看不到回退效果
  • 未限制x轴显示范围:没有动态调整坐标轴的可视区间,就算数据区间移动,视图也不会跟随变化
  • 缺少步长上限判断:没有限制step的最大值,当滑动到数据末尾时会出现索引越界错误
修复后完整代码
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df = pd.read_csv('all_stocks_5yr.csv')
df_apple = df[df['Name'] == 'AAPL'].copy()
df_apple['date'] = pd.to_datetime(df_apple['date'])
df_apple.reset_index(drop=True, inplace=True)

bars_to_display = 60
step = 0
max_step = len(df_apple) - bars_to_display

x = np.arange(0,len(df_apple))
fig, (ax, ax2) = plt.subplots(2, figsize=(12,8), gridspec_kw={'height_ratios': [4, 1]}, sharex = True)
val_array = df_apple.to_dict('records')
mx = df_apple['volume'].max()*1.1
yticks_ax2 = np.arange(0, mx+1, mx/4)
yticks_labels_ax2 = ['{:.2f} mi'.format(i/1000000) for i in yticks_ax2]

def update_chart():
    # 清空旧绘图
    ax.clear()
    ax2.clear()
    
    # 重新应用轴样式
    ax2.set_xticks(x[step:step+bars_to_display:3])
    ax2.set_xticklabels(df_apple.date.dt.date[step:step+bars_to_display:3], rotation=45, ha='right')
    ax.set_xticks(x[step:step+bars_to_display], minor=True)
    ax.set_ylabel('USD')
    ax2.set_ylabel('Volume')
    ax.xaxis.grid(color='black', linestyle='dashed', which='both', alpha=0.1)
    ax2.set_axisbelow(True)
    ax2.yaxis.grid(color='black', linestyle='dashed', which='both', alpha=0.1)
    ax.spines['right'].set_visible(False)
    ax.spines['left'].set_visible(False)
    ax.spines['top'].set_visible(False)
    ax2.spines['right'].set_visible(False)
    ax2.spines['left'].set_visible(False)
    ax2.yaxis.tick_right()
    plt.yticks(yticks_ax2[1:-1], yticks_labels_ax2[1:-1])
    ax2.set_ylim(0,mx)
    ax.set_title('Apple Stock Price\n', loc='left', fontsize=20)
    ax.set_xlim(step-0.5, step + bars_to_display + 0.5)
    
    # 绘制当前区间K线
    for i in range(step, step + bars_to_display):
        color = '#2CA453'
        if val_array[i]['open'] > val_array[i]['close']: 
            color= '#F04730'
        ax.plot([x[i], x[i]], [val_array[i]['low'], val_array[i]['high']], color=color)
        ax.plot([x[i], x[i]-0.1], [val_array[i]['open'], val_array[i]['open']], color=color)
        ax.plot([x[i], x[i]+0.1], [val_array[i]['close'], val_array[i]['close']], color=color)
        ax2.bar(x[i], val_array[i]['volume'] , color='lightgrey')
    fig.canvas.draw_idle()

# 初始化绘图
update_chart()

def on_keyboard(event):
    global step
    if event.key == 'right':
        step += 1
        if step > max_step:
            step = max_step
    elif event.key == 'left':
        step -= 1
        if step <= 0: 
            step=0
    update_chart()

plt.gcf().canvas.mpl_connect('key_press_event', on_keyboard)
plt.tight_layout()
plt.show()

内容的提问来源于stack exchange,提问作者Hugo Araújo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:09:03