values display at upper left
cursor response to mouse move, cursor center always snaps to the plot
import matplotlib.pyplot as plt
import numpy as np
import datetime as dt
import pandas_datareader.data as web
class SnaptoCursor(object):
"""
Like Cursor but the crosshair snaps to the nearest x, y point.
For simplicity, this assumes that *x* is sorted.
"""
def __init__(self, ax, x, y, numberIndex):
self.ax = ax
self.lx = ax.axhline(color='r') # the horiz line
self.ly = ax.axvline(color='r') # the vert line
self.x = x
self.y = y
self.nIndex = numberIndex
# text location in axes coords
self.txt = ax.text(0.05, 0.9, '', transform=ax.transAxes)
def mouse_move(self, event):
if not event.inaxes:
return
x, y = event.xdata, event.ydata
indx = min(np.searchsorted(self.nIndex, x), len(self.x) - 1)
x = self.x[indx]
y = self.y[indx]
# update the line positions
self.lx.set_ydata(y)
self.ly.set_xdata(indx)
self.txt.set_text('x=%s\ny=%1.2f' % (x.strftime('%b %d %Y'), y))
self.ax.figure.canvas.draw()
start = dt.datetime(2014, 1, 1)
end = dt.datetime(2019, 10, 30)
ticker = 'BNS'
df = web.DataReader(ticker, 'yahoo', start, end)
print(df[:5])
print(df['Adj Close'].values[:5])
print(df['Adj Close'].index[:5])
x = df['Adj Close'].index
y = df['Adj Close'].values
#number index is need for the cursor position, xaxis is mapped with integer first and converted to date later
x_num_index = np.arange(0, len(x), 1)
fig, ax = plt.subplots()
ax.plot(x_num_index, y)
snap_cursor = SnaptoCursor(ax, x, y, x_num_index)
fig.canvas.mpl_connect('motion_notify_event', snap_cursor.mouse_move)
#get default # of lables on x axis
n = len(ax.get_xticklabels())
print(n)
x_format = x.strftime('%b %d %Y')
xlabels = [x_format[int(i*len(x)/n)] for i in range(0, n)]
print(xlabels)
ax.set_xticklabels(xlabels)
ax.set_ylim([np.min(y), np.max(y)])
ax.set_title('Closing Price of %s' %(ticker))
plt.gcf().autofmt_xdate()
plt.show()
----------------------------
#logs
High Low Open Close Volume Adj Close
Date
2014-01-02 62.750000 61.939999 62.549999 61.980000 425800.0 43.690678
2014-01-03 61.689999 61.060001 61.490002 61.500000 351100.0 43.790367
2014-01-06 61.360001 60.480000 61.340000 60.750000 427300.0 43.256340
2014-01-07 60.820000 59.869999 60.610001 59.889999 547600.0 42.643982
2014-01-08 59.840000 59.330002 59.770000 59.630001 540700.0 42.458855
[43.69067764 43.79036713 43.25634003 42.64398193 42.45885468]
DatetimeIndex(['2014-01-02', '2014-01-03', '2014-01-06', '2014-01-07',
'2014-01-08'],
dtype='datetime64[ns]', name='Date', freq=None)
10
['Jan 02 2014', 'Aug 01 2014', 'Mar 04 2015', 'Oct 01 2015', 'May 03 2016', 'Nov 30 2016', 'Jul 03 2017', 'Feb 01 2018', 'Aug 31 2018', 'Apr 04 2019']
reference:
http://chuanshuoge2.blogspot.com/2019/10/python-programming-for-finance-1.html
https://stackabuse.com/how-to-format-dates-in-python/
https://matplotlib.org/3.1.0/gallery/misc/cursor_demo_sgskip.html
https://stackoverflow.com/questions/11244514/modify-tick-label-text
No comments:
Post a Comment