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
相关产品推荐
相关产品推荐

