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

时间:2016-09-28 20:35:50

标签: python pandas matplotlib graph interactive

我试图在用户点击有效点时用matplotlib交互式绘制OHLC图。数据存储为表格

的pandas数据帧
candlestick2_ohlc(ax1, df['PX_OPEN'],df['PX_HIGH'],df['PX_LOW'],df['PX_LAST'],width=1)

我正在用matplotlib的烛台功能绘图:

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()

绘制时看起来像这样:

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

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

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

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

PurchaseOrderHeader:
PurchaseOrderID  VendorID   OrderDate                TotalDue
1                1580       2011-04-16 00:00:00.000  222.1492
2                1496       2011-04-16 00:00:00.000  300.6721
3                1494       2011-04-16 00:00:00.000  9776.2665
4                1650       2011-04-16 00:00:00.000  189.0395
5                1654       2011-04-30 00:00:00.000  22539.0165
6                1664       2011-04-30 00:00:00.000  16164.0229
7                1678       2011-04-30 00:00:00.000  64847.5328

PurchaseOrderDetail:
PurchaseOrderID  PurchaseOrderDetailID  OrderQty    ProductID
1                1                      4           1
2                2                      3           359
2                3                      3           360
3                4                      550         530
4                5                      3           4
5                6                      550         512
6                7                      550         513
7                8                      550         317
7                9                      550         318
7                10                     550         319

然而,candlestick2_ohlc不会选择'选择器' ARG。关于如何解决这个问题的任何提示?

由于

1 个答案:

答案 0 :(得分: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()