2016-10-05 2 views
0

J'essaie de créer un graphique OHLC tracé avec matplotlib interactif lorsque l'utilisateur clique sur un point valide. Les données sont stockées en tant que trame de données de pandas géants de la formeL'objet AxesSubplot n'a pas d'attribut erreur 'get_xdata' lors du tracé de la carte matplotlib OHLC

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 

Je comploter avec la fonction chandelier de matplotlib:

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

Quand comploté il semble somthing comme ceci:

Je veux que la console imprime la valeur du point cliqué, la date et si c'est un ouvert, haut bas ou proche. Jusqu'à présent, j'ai quelque chose comme:

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

Quand je lance ce graphique apparaît cependant cliquant sur n'importe où sur le graphique, il donne l'erreur:

AttributeError: objet « AxesSubplot » n'a pas d'attribut « get_xdata ». Est-ce que le candlestick2_ohlc ne supporte pas cela?

En outre, quel est le type d'instance de matplotlibs candlestick2_ohlc afin que je puisse vérifier si l'utilisateur a cliqué sur un point réel?

Par exemple, pour un graphique de ligne, on pourrait utiliser pour vérifier

isinstance(event.artist,Line2D) 

Répondre

0

Tout d'abord, candlestick2_ohlc semble créer et retourner un tuple d'une instance matplotlib.collections.LineCollection, et une instance matplotlib.collections.PolyCollection.

Nous devons rendre chacune de ces instances sélectionnable, avant de faire quoi que ce soit d'autre.

Si vous prenez les cas où ils sont renvoyés de candlestick2_ohlc, c'est un outil facile en utilisant 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) 

Ils sont ce que nous devons vérifier dans la fonction 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()))