【问题标题】:AxesSubplot' object has no attribute 'get_xdata' error when plotting OHLC matplotlib chart绘制 OHLC matplotlib 图表时,AxesSubplot' 对象没有属性 'get_xdata' 错误
【发布时间】:2017-02-13 15:18:12
【问题描述】:

我正在尝试在用户单击有效点时使用 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)

绘制时看起来像这样:

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

fig, ax1 = plt.subplots()
ax1.set_picker(True)
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()

当我运行它时,图表会出现,但是点击图表上的任意位置时会出现错误:

AttributeError:“AxesSubplot”对象没有属性“get_xdata”。烛台2_ohlc 不支持这个吗?

另外,matplotlibs 的烛台2_ohlc 的实例类型是什么,以便我可以检查用户是否点击了实际点?

例如,对于折线图,可以使用检查

isinstance(event.artist,Line2D)

【问题讨论】:

    标签: python pandas matplotlib graph interactive


    【解决方案1】:

    首先,candlestick2_ohlc 似乎创建并返回了一个 matplotlib.collections.LineCollection 实例和一个 matplotlib.collections.PolyCollection 实例的元组。

    在我们做任何其他事情之前,我们需要使这些实例中的每一个都可以选择。

    如果您在从candlestick2_ohlc 返回时获取这些实例,则使用set_picker 很容易:

    linecoll, polycoll = candlestick2_ohlc(ax1, df['PX_OPEN'],df['PX_HIGH'],df['PX_LOW'],df['PX_LAST'],width=0.4)
    
    linecoll.set_picker(True)
    polycoll.set_picker(True)
    

    它们是我们需要在onpick1 函数中检查的内容:

    import matplotlib.collections as collections
    
    def onpick1(event):
    
        # Check we have clicked on one of the collections created by candlestick2_ohlc
        if isinstance(event.artist, (collections.LineCollection, collections.PolyCollection)):
    
            thiscollection = event.artist
            # Find which box or line we have clicked on
            ind = event.ind[0]
    
            # Find the vertices of the object
            verts = thiscollection.get_paths()[ind].vertices
    
            if isinstance(event.artist, collections.LineCollection):
                print "Errorbar line dimensions"
            elif isinstance(event.artist, collections.PolyCollection):
                print "Box dimensions"
    
            # Print the minimum and maximum extent of the object in x and y
            print( "X = {}, {}".format(verts[:, 0].min(), verts[:, 0].max()) )
            print( "Y = {}, {}".format(verts[:, 1].min(), verts[:, 1].max()) )
    

    【讨论】:

      猜你喜欢
      • 2019-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多