matplotlib / mplfinance

Financial Markets Data Visualization using Matplotlib
https://pypi.org/project/mplfinance/
Other
3.62k stars 625 forks source link

MultiCursor #303

Open robert48173 opened 3 years ago

robert48173 commented 3 years ago

Daniel, thank you for excellent project. My question is this: There is a feature in matplotlib which provides a vertical (default) and/or horizontal line cursor shared between multiple axes. Is it possible to have something like that in mplfinance?

This is the sample code they provided with their help screen:

from matplotlib.widgets import MultiCursor
import matplotlib.pyplot as plt
import numpy as np

fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)
t = np.arange(0.0, 2.0, 0.01)
ax1.plot(t, np.sin(2*np.pi*t))
ax2.plot(t, np.sin(4*np.pi*t))

multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1,
                    horizOn=False, vertOn=True)
plt.show()
DanielGoldfarb commented 3 years ago

@robert48173 This a really good idea. It should be relatively easy to implement in panels mode by adding a kwarg for it to mpf.plot()

In the meantime, as an easy workaround, use returnfig=True:

fig, axlist = mpf.plot(data,...,returnfig=True)
multi  = MultiCursor(fig.canvas, axlist, color='r', lw=1)
mpf.show()

I tried this with the MACD example towards the end of the panels notebook and it looks great:

import pandas as pd
import mplfinance as mpf
from matplotlib.widgets import MultiCursor

idf = pd.read_csv('../data/SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True)
df  = idf.loc['2011-07-01':'2011-12-30',:]

exp12 = df['Close'].ewm(span=12, adjust=False).mean()
exp26 = df['Close'].ewm(span=26, adjust=False).mean()
macd  = exp12 - exp26

signal    = macd.ewm(span=9, adjust=False).mean()
histogram = macd - signal
apds = [mpf.make_addplot(exp12,color='lime'),
        mpf.make_addplot(exp26,color='c'),
        mpf.make_addplot(histogram,type='bar',width=0.7,panel=1,
                         color='dimgray',alpha=1,secondary_y=False),
        mpf.make_addplot(macd,panel=1,color='fuchsia',secondary_y=True),
        mpf.make_addplot(signal,panel=1,color='b',secondary_y=True),
       ]

fig, axlist = mpf.plot(df,type='candle',addplot=apds,figscale=1.1,figratio=(8,5),title='\nMACD',
                       style='blueskies',volume=True,volume_panel=2,panel_ratios=(6,3,2),returnfig=True)
multi = MultiCursor(fig.canvas, axlist, color='r',lw=1.2)
mpf.show()

multicursor_macd

martynmarty commented 3 years ago

Daniel, first of of thank you for your work on mplfinance.

I think this update introduced a bug using the horizontal lines.

Installing collected packages: mplfinance Successfully installed mplfinance-0.12.7a4

Using this code:

close_line = dict( hlines=[last_close], colors=['grey'], linestyle='--', linewidths=(1), alpha=(0.4))

fig, axlist = mpf.plot( .. hlines=close_line, .. returnfig=True)

`--------------------------------------------------------------------------- TypeError Traceback (most recent call last)

in () 114 figscale=1.5, 115 # xlim=xlim, --> 116 returnfig=True) 117 118 ax1 = axlist[0] 1 frames /usr/local/lib/python3.6/dist-packages/mplfinance/_arg_validators.py in _process_kwargs(kwargs, vkwargs) 244 import inspect 245 v = inspect.getsource(vkwargs[key]['Validator']).strip() --> 246 raise TypeError('kwarg "'+key+'" validator returned False for value: "'+str(value)+'"\n '+v) 247 248 # --------------------------------------------------------------- TypeError: kwarg "hlines" validator returned False for value: "{'hlines': ['225.78'], 'colors': ['grey'], 'linestyle': '--', 'linewidths': 1, 'alpha': 0.4}" 'Validator' : lambda value: _hlines_validator(value) },` This is while using Google Colab which automatically updated this morning, local version '0.12.7a0' has no problem.
DanielGoldfarb commented 3 years ago

@martynmarty This Issue #303 has nothing to do with the introduction of version '0.12.7a4'. Please create a new issue.

I have tried to reproduce the issue as you have posted it above, but the code works fine for me (with version 0.12.7a4).

When you repost this as a new issue, are there any more Traceback details that you can post?

The Traceback output:

TypeError: kwarg "hlines" validator returned False for value: "{'hlines': ['225.78'], 'colors': ['grey'], 'linestyle': '--', 'linewidths': 1, 'alpha': 0.4}"
'Validator' : lambda value: _hlines_validator(value) },`

appears to b a valid hlines value. It's not making sense that the validator would return False.

manuelwithbmw commented 3 years ago
from matplotlib.widgets import MultiCursor

Wow Daniel, @DanielGoldfarb this cursor looks fantastic, thank you! Is it normal that when you generate a plot having it on it, after you 'Zoom in rectangle' you lose the cursor's availability?

DanielGoldfarb commented 3 years ago

@manuelwithbmw ... I don't know. This was my first experience with MultiCursor. It was @robert48173 's idea.

manuelwithbmw commented 3 years ago

@manuelwithbmw ... I don't know. This was my first experience with MultiCursor. It was @robert48173 's idea.

Thank you Robert @robert48173 for the tip!

DanielGoldfarb commented 3 years ago

@martynmarty Also, perhaps include more of your code and your data. Or try to reproduce using the same example that I did. I used the first example from the using lines notebook, by inserting the following code after cell 6:

last_close = daily['Close'].iloc[-1]
print('last_close=',last_close)
close_line = dict( hlines=[last_close], colors=['grey'], linestyle='--', linewidths=(1), alpha=(0.4))
fig, axlist = mpf.plot(daily,hlines=close_line,type='candle',returnfig=True)
print(mpf.__version__)
martynmarty commented 3 years ago

@DanielGoldfarb

My sincere apologies, the example code you provided worked, the last_close was formatted as string in my Notebook.

DanielGoldfarb commented 3 years ago

the last_close was formatted as string in my Notebook.

Ahh. I should have notice that if I read the exception output more carefully; it shows that here that it is a string:

TypeError: kwarg "hlines" validator returned False for value: "{'hlines': ['225.78'], 'colors': ['grey'], 'linestyle': '--', 'linewidths': 1, 'alpha': 0.4}"
'Validator' : lambda value: _hlines_validator(value) },`
robert48173 commented 3 years ago

@DanielGoldfarb,

The workaround works for me AND I LOVE IT! Thanks.

spitzbubchen commented 3 years ago

This works well for me. I think the issue can be closed. I also think this example should be placed on the README.md as it is something many users are probably looking for.