1

I want to plot the close price of INS as below and it works. Then I want to add the cursor when hovering on the graph. I follow the demo from https://matplotlib.org/3.1.0/gallery/misc/cursor_demo_sgskip.html and that is what I want.

enter image description here

But when I added these lines into the code, it shows value error. Initially I use epoch time as x-axis and I thought that is the problem, so I convert epoch time to datetime but it is still not working and plot nothing.

snap_cursor = SnaptoCursor(ax, secs, df['close'])
fig.canvas.mpl_connect('motion_notify_event', snap_cursor.mouse_move)

Traceback (most recent call last): File "c:\Users\Sam.vscode\extensions\ms-python.python-2020.6.89148\pythonFiles\ptvsd_launcher.py", line 48, in main(ptvsdArgs) File "c:\Users\Sam.vscode\extensions\ms-python.python-2020.6.89148\pythonFiles\lib\python\old_ptvsd\ptvsd_main_.py", line 432, in main run() File "c:\Users\Sam.vscode\extensions\ms-python.python-2020.6.89148\pythonFiles\lib\python\old_ptvsd\ptvsd_main_.py", line 316, in run_file runpy.run_path(target, run_name='main') File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\runpy.py", line 263, in run_path pkg_name=pkg_name, script_name=fname) File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\runpy.py", line 96, in _run_module_code mod_name, mod_spec, pkg_name, script_name) File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "c:\Users\Sam\OneDrive\Project\stock\test.py", line 89, in plt.gcf().autofmt_xdate() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\figure.py", line 632, in autofmt_xdate for label in self.axes[0].get_xticklabels(which=which): File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axes_base.py", line 3355, in get_xticklabels return self.xaxis.get_ticklabels(minor=minor, which=which) File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axis.py", line 1320, in get_ticklabels return self.get_majorticklabels() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axis.py", line 1276, in get_majorticklabels File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axis.py", line 1431, in get_major_ticks numticks = len(self.get_majorticklocs()) File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axis.py", line 1348, in get_majorticklocs return self.major.locator() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\dates.py", line 1338, in call self.refresh() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\dates.py", line 1364, in refresh dmin, dmax = self.viewlim_to_dt() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\dates.py", line 1098, in viewlim_to_dt .format(vmin)) ValueError: view limit minimum -36879.777083333334 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units

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):
        self.ax = ax
        self.lx = ax.axhline(color='k')  # the horiz line
        self.ly = ax.axvline(color='k')  # the vert line
        self.x = x
        self.y = y
        # text location in axes coords
        self.txt = ax.text(0.7, 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.x, 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(x)

        self.txt.set_text('x=%1.2f, y=%1.2f' % (x, y))
        print('x=%1.2f, y=%1.2f' % (x, y))
        self.ax.figure.canvas.draw()

data = td.pricehistory("INS")
df = pd.DataFrame(data['candles'])
df['datetime'] = df.apply(lambda x: datetime.datetime.fromtimestamp(x['datetime']/1000),axis=1)
secs = df['datetime']
fig, ax = plt.subplots(1, 1)  
ax.plot(secs,df['close']) 

snap_cursor = SnaptoCursor(ax, secs, df['close'])
fig.canvas.mpl_connect('motion_notify_event', snap_cursor.mouse_move)

plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%d-%m-%y %H:%M:%S')
plt.gca().xaxis.set_major_formatter(myFmt)

plt.show()

1 Answer 1

1

I'm not familiar with SnaptoCursor, but have you considered using plotly instead?

Saves many lines of code and is very user-friendly:

# install plotly library
!pip install plotly

# import express module
import plotly.express as px

# plot interactive line chart
fig = px.line(data=df, x="datetime", y="close")
fig.show()

It's very flexible too. Here is the documentation: https://plotly.com/python/line-charts/

You can interact with the plots using the cursor too, for example: enter image description here

Hope this helps, though of course it's different to what you were trying to do!

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. That is another library i can explore to

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.