AxesSubplot' object has no attribute 'get_xdata' error when plotting OHLC matplotlib chart
<p>I am trying to make a OHLC graph plotted with matplotlib interactive upon the user clicking on a valid point. The data is stored as a pandas dataframe of the form</p>

<pre><code>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
</code></pre>

<p>I am plotting it with matplotlib's candlestick function:</p>

<pre><code>candlestick2_ohlc(ax1, df['PX_OPEN'],df['PX_HIGH'],df['PX_LOW'],df['PX_LAST'],width=1)
</code></pre>

<p>When plotted it looks somthing like this:</p>

<p><a href="http://i.stack.imgur.com/EC0oX.png" rel="nofollow"><img src="http://i.stack.imgur.com/EC0oX.png" alt=""></a></p>

<p>I want the console to print out the value of the point clicked, the date and whether it is an open, high low or close. So far I have something like:</p>

<pre><code>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()
</code></pre>

<p>When I run this the graph appears however upon clicking anywhere on the graph it gives error:  </p>

<p>AttributeError: 'AxesSubplot' object has no attribute 'get_xdata'. Does the candlestick2_ohlc not support this? </p>

<p>Additionally, what is the instance type of matplotlibs candlestick2_ohlc so I can check if the user has clicked on an actual point?</p>

<p>For example for a line graph one could use check for</p>

<pre><code>isinstance(event.artist,Line2D)
</code></pre>

<p>First of all, <code>candlestick2_ohlc</code> appears to create and return a tuple of a <code>matplotlib.collections.LineCollection</code> instance, and a <code>matplotlib.collections.PolyCollection</code> instance. </p>

<p>We need to make each of these instances pickable, before we do anything else. </p>

<p>If you grab those instances as they are returned from <code>candlestick2_ohlc</code>, this is an easy using <code>set_picker</code>:</p>

<pre><code>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)
</code></pre>

<p>They are what we need to check for in the <code>onpick1</code> function:</p>

<pre><code>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()) )
</code></pre>

python pandas matplotlib graph interactive