首页 文章

如何在matplotlib中制作可点击的python烛台图表

提问于
浏览
2

我试图在用户点击有效点时使用matplotlib交互式绘制OHLC图 . 数据存储为表单的pandas数据帧

index       PX_BID  PX_ASK  PX_LAST  PX_OPEN  PX_HIGH  PX_LOW
2016-07-01  1.1136  1.1137   1.1136   1.1106   1.1169  1.1072
2016-07-04  1.1154  1.1155   1.1154   1.1143   1.1160  1.1098
2016-07-05  1.1076  1.1077   1.1076   1.1154   1.1186  1.1062
2016-07-06  1.1100  1.1101   1.1100   1.1076   1.1112  1.1029
2016-07-07  1.1062  1.1063   1.1063   1.1100   1.1107  1.1053

我用matplotlib的烛台功能绘制它:

candlestick2_ohlc(ax1, df['PX_OPEN'],df['PX_HIGH'],df['PX_LOW'],df['PX_LAST'],width=1)

绘制时看起来像这样:

https://pythonprogramming.net/static/images/matplotlib/candlestick-ohlc-graphs-matplotlib-tutorial.png

我希望控制台打印出点击的点的值,日期以及它是开放,高低还是关闭 . 到目前为止我有类似的东西:

fig, ax1 = plt.subplots()

ax1.set_title('click on points', picker=True)
ax1.set_ylabel('ylabel', picker=True, bbox=dict(facecolor='red'))
line = candlestick2_ohlc(ax1, df['PX_OPEN'],df['PX_HIGH'],df['PX_LOW'],df['PX_LAST'],width=0.4)

def onpick1(event):
    if isinstance(event.artist, (lineCollection, barCollection)):
        thisline = event.artist
        xdata = thisline.get_xdata()
        ydata = thisline.get_ydata()
        ind = event.ind
        #points = tuple(zip(xdata[ind], ydata[ind]))
        #print('onpick points:', points)
        print( 'X='+str(np.take(xdata, ind)[0]) ) # Print X point
        print( 'Y='+str(np.take(ydata, ind)[0]) ) # Print Y point

fig.canvas.mpl_connect('pick_event', onpick1)
plt.show()

但是,当运行并点击点时,此代码不会打印任何内容 . 当我查看交互式matplotlib图的示例时,它们往往在绘图函数中有一个参数,例如:

line, = ax.plot(rand(100), 'o', picker=5)

但是,烛台2_ohlc不会采取'选择器'arg . 关于如何解决这个问题的任何提示?

谢谢

1 回答

  • 1

    您需要设置 set_picker(True) 以启用拾取事件或将点容差作为浮点数给出(请参阅http://matplotlib.org/api/artist_api.html#matplotlib.artist.Artist.set_picker) .

    所以在你的情况下 ax1.set_picker(True) 如果你想要当mouseevent结束 ax1 时触发挑选事件 .

    您可以在烛台图表的元素上启用选择事件 . 我阅读了文档,candlestick2_ohlc返回了两个对象的元组: LineCollectionPolyCollection . 因此,您可以命名这些对象并将选择器设置为true

    (lines,polys) = candlestick2_ohlc(ax1, ...)
    lines.set_picker(True) # collection of lines in the candlestick chart
    polys.set_picker(True) # collection of polygons in the candlestick chart
    

    事件 ind = event.ind[0] 的索引将告诉您集合中的哪个元素包含鼠标事件( event.ind 返回索引列表,因为鼠标事件可能涉及多个项目) .

    在烛台上触发拣货事件后,您可以打印原始数据框中的数据 .

    这是一些有效的代码

    import matplotlib.pyplot as plt
    from matplotlib.collections import LineCollection, PolyCollection
    from matplotlib.text import Text
    from matplotlib.finance import candlestick2_ohlc
    import numpy as np
    import pandas as pd
    
    np.random.seed(0)
    dates = pd.date_range('20160101',periods=7)
    df = pd.DataFrame(np.reshape(1+np.random.random_sample(42)*0.1,(7,6)),index=dates,columns=["PX_BID","PX_ASK","PX_LAST","PX_OPEN","PX_HIGH","PX_LOW"])
    df['PX_HIGH']+=.1
    df['PX_LOW']-=.1
    
    fig, ax1 = plt.subplots()
    
    ax1.set_title('click on points', picker=20)
    ax1.set_ylabel('ylabel', picker=20, bbox=dict(facecolor='red'))
    
    (lines,polys) = candlestick2_ohlc(ax1, df['PX_OPEN'],df['PX_HIGH'],df['PX_LOW'],df['PX_LAST'],width=0.4)
    lines.set_picker(True)
    polys.set_picker(True)
    
    def onpick1(event):
        if isinstance(event.artist, (Text)):
            text = event.artist
            print 'You clicked on the title ("%s")' % text.get_text()
        elif isinstance(event.artist, (LineCollection, PolyCollection)):   
            thisline = event.artist
            mouseevent = event.mouseevent
            ind = event.ind[0]
            print 'You clicked on item %d' % ind
            print 'Day: ' + df.index[ind].normalize().to_datetime().strftime('%Y-%m-%d')
            for p in ['PX_OPEN','PX_OPEN','PX_HIGH','PX_LOW']:
                print p + ':' + str(df[p][ind])    
            print('x=%d, y=%d, xdata=%f, ydata=%f' %
              ( mouseevent.x, mouseevent.y, mouseevent.xdata, mouseevent.ydata))
    
    
    
    fig.canvas.mpl_connect('pick_event', onpick1)
    plt.show()
    

相关问题