首页 > 解决方案 > 单击按钮时向 Matplotlib 动画添加箭头

问题描述

我现在正在使用 matplotlib.animation 我得到了一些好的结果。我想在图表中添加一些东西,但找不到方法。

  1. 单击按钮时添加“买入”/“卖出”箭头,让我们说“1” - 买入,“2”表示卖出。

  2. 简单的标签/图例,将显示当前实时值(开盘、高盘、低盘、收盘、成交量)

这是我下面的代码:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import pandas as pd
import mplfinance as mpf
import matplotlib.animation as animation

idf = pd.read_csv('aapl.csv',index_col=0,parse_dates=True)



#df = idf.loc['2011-07-01':'2012-06-30',:]

pkwargs=dict(type='candle',mav=(20,200))

fig, axes = mpf.plot(idf.iloc[0:20],returnfig=True,volume=True,
                     figsize=(11,8),panel_ratios=(3,1),
                     title='\n\nS&P 500 ETF',**pkwargs,style='starsandstripes')
ax1 = axes[0]
ax2 = axes[2]
ax1.spines['top'].set_visible(True)
ax1.grid(which='major', alpha=0.1)
ax2.grid(which='major', alpha=0.1)




#fig = plt.figure()

def run_animation():
    ani_running = True

    def onClick(event):
        nonlocal ani_running
        
        if ani_running:
            ani.event_source.stop()
            ani_running = False
        else:
            ani.event_source.start()
            ani_running = True


    def animate(ival):
        if (20+ival) > len(idf):
            print('no more data to plot')
            ani.event_source.interval *= 3
            if ani.event_source.interval > 12000:
                exit()
            return
        #print("here")

    

        #mpf.plot(idf,addplot=apd)

        data = idf.iloc[100+ival:(250+ival)]
        print(idf.iloc[ival+250])

        ax1.clear()
        ax2.clear()

        mpf.plot(data,ax=ax1,volume=ax2,**pkwargs,style='yahoo')


    fig.canvas.mpl_connect('button_press_event', onClick)
    ani = animation.FuncAnimation(fig, animate, interval=240)
run_animation()
mpf.show()

在此处输入图像描述

标签: pythonmatplotlibchartsmatplotlib-animation

解决方案


当你说你想要的时候,我不清楚你到底想要什么add "buy"/ "sell" arrow,但我可以回答你关于创造传奇的问题。

我认为最简单的事情是通过指定颜色和标签来构建自定义图例。标签会随着动画的进行而改变,因此您需要在animate清除两个轴并绘制最新数据后更新函数中的图例 - 我假设您正在打印的 DataFrame 行是您要显示的行在传说中:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import pandas as pd
import mplfinance as mpf
import matplotlib.patches as mpatches

idf = pd.read_csv('https://raw.githubusercontent.com/matplotlib/sample_data/master/aapl.csv',index_col=0,parse_dates=True)

#df = idf.loc['2011-07-01':'2012-06-30',:]

pkwargs=dict(type='candle',mav=(20,200))

fig, axes = mpf.plot(idf.iloc[0:20],returnfig=True,volume=True,
                     figsize=(11,8),panel_ratios=(3,1),
                     title='\n\nS&P 500 ETF',**pkwargs,style='starsandstripes')
ax1 = axes[0]
ax2 = axes[2]

## define the colors and labels
colors = ["red","green","red","green"]
labels = ["Open", "High", "Low", "Close"]

#fig = plt.figure()

def run_animation():
    ani_running = True


    def onClick(event):
        nonlocal ani_running
        
        if ani_running:
            ani.event_source.stop()
            ani_running = False
        else:
            ani.event_source.start()
            ani_running = True


    def animate(ival):
        if (20+ival) > len(idf):
            print('no more data to plot')
            ani.event_source.interval *= 3
            if ani.event_source.interval > 12000:
                exit()
            return
        #print("here")

    

        #mpf.plot(idf,addplot=apd)

        data = idf.iloc[100+ival:(250+ival)]
        print(idf.iloc[ival+250])

        ## what to display in legend
        values = idf.iloc[ival+250][labels].to_list()
        legend_labels = [f"{l}: {str(v)}" for l,v in zip(labels,values)]
        handles = [mpatches.Patch(color=c, label=ll) for c,ll in zip(colors, legend_labels)]

        ax1.clear()
        ax2.clear()

        mpf.plot(data,ax=ax1,volume=ax2,**pkwargs,style='yahoo')

        ## add legend after plotting
        ax1.legend(handles=handles, loc=2)

    fig.canvas.mpl_connect('button_press_event', onClick)
    ani = animation.FuncAnimation(fig, animate, interval=240)
run_animation()
mpf.show()

在此处输入图像描述


推荐阅读