I am trying to use addplot to highlight specific candlestick data on the chart. The way I am trying is:
addSignals = mpf.make_addplot(dfTest['close'], type='scatter',marker=mymarker,markersize=45,color=color)
mpf.plot(dfDATE1,type='candle', style='binance',addplot=addSignals)
The error I am getting is: ValueError: x and y must be the same size
[BEFORE SPLITTING DATAFRAMES] I have a column with a reading of 1 if the signal condition is correct, and I isolated those into their own dataframe, dfTest. The one I am trying to use to addplot with scatter signals.
The dataframe for the main `mpf.plot() contains the complete data inside, but obviously minus the signal column since mpf needs OHLC and date index only. I just want to highlight my signal data with a simple marker.
However I am not sure how to do that. If this question is not clear please let me know so I can try and reword it.
Not entirely clear, but possibly clear enough. It would be better if I could see the code that generates dfTest['close'].
That said, I'm thinking perhaps your problem is this:
len(dfTest['close']) == len(dfDATE1) must be True.
If not, this won't work.
If you want markers in dfTest['close'] to be sparse, you should fill the non-marker values with float('nan') or numpy.nan.
Please let me know if that helps. Or if you have any other questions. All the best. --Daniel
I applied a function with if statements leading to a yes or no answer on the main dataframe.
Then from there I made a new dataframe from the rows containing the data I am looking for:
dfTest = dfDATE.loc[(dfDATE['type1']=='TYPE 1')]
So at this point I have isolated from the main dataframe, the candles I am looking for, to place a marker on.
--
Reading what you told me here: "If you want markers in dfTest['close'] to be sparse, you should fill the non-marker values with float('nan') or numpy.nan."
So I should go back to a copy of the main dataframe without filtering it, but fill any value != to what I want to nan values?
Thanks for the help so far
Again, it's very difficult for me to provide an answer without seeing your code and data.
If I could see your code and data, then I could make a specific recommendation regarding your code.
Without it, I can only provide an example that is a guess as to what may be needed in your code:
So I should go back to a copy of the main dataframe without filtering it, but fill any value != to what I want to nan values?
... probably yes, or something like this:
print(df)
Open High Low Close
Date
2014-09-11 1992.849976 1997.650024 1985.930054 1997.449951
2014-09-12 1996.739990 1996.739990 1980.260010 1985.540039
2014-09-15 1986.040039 1987.180054 1978.479980 1984.130005
2014-09-16 1981.930054 2002.280029 1979.060059 1998.979980
2014-09-17 1999.300049 2010.739990 1993.290039 2001.569946
2014-09-18 2003.069946 2012.339966 2003.069946 2011.359985
2014-09-19 2012.739990 2019.260010 2006.589966 2010.400024
ranges = df['High'] - df['Low']
signal = pd.DataFrame(ranges.loc[(ranges < 10.0)],columns=['Signal'])
print(signal)
Signal
Date
2014-09-15 8.700074
2014-09-18 9.270020
mpf.make_addplot(), signal needs to match the length and index being passed into mpf.plot().nan values.print(df_sparse)
Signal
Date
2014-09-11 NaN
2014-09-12 NaN
2014-09-15 NaN
2014-09-16 NaN
2014-09-17 NaN
2014-09-18 NaN
2014-09-19 NaN
for ix,val in zip(signal.index,signal.values):
df_sparse.loc[ix] = val
print(df_sparse)
Signal
Date
2014-09-11 NaN
2014-09-12 NaN
2014-09-15 8.700074
2014-09-16 NaN
2014-09-17 NaN
2014-09-18 9.270020
2014-09-19 NaN
```
Thank you, very informative.
Your code will no doubt help me and others in the future. You put me on the right path today to fix it, and what I done was very hacky but it works...
The code I done: before with the function was:
if condition true: return 'TYPE 1'
else: return 'undefined'
Now, the code is:
if condition true: return data['close']
else: return np.nan
Then apply function: df['type1'] = df.apply(type1,axis=1)
toplot = mpf.make_addplot(df['type1'],scatter=True)
mpf.plot(dfDATE1,type='candle',style='binance',addplot=toplot)
Appreciate it! Why don't you sign up for Brave BAT Rewards? Us and others can tip you from github :)
So my function worked, until I needed to plot the 2 different types of signals.
At which point I come back to your answer:
_"But in order to plot the Signal data with mpf.make_addplot(),
the length and index of signal needs to match the length and index being passed into mpf.plot().
I can do this by first creating a dataframe that is the correct length, with the correct index, but all nan values.
then I loop through the signal, and insert the non-nan values into the correctly sized and indexed dataframe:"_
And the code:
df_sparse = pd.DataFrame([float('nan')]*len(df),index=df.index,columns=['Signal'])
for ix,val in zip(signal.index,signal.values):
df_sparse.loc[ix] = val
This solved all the problems I've been having.
Thank you so much!
I glad it worked for you. By the way, your approach of
if condition true: return data['close']
else: return np.nan
is actually a very good way to do it. You should be able to apply two different "conditions" to get two different signals that way. But, depending on the existing code, as you found, it may be cleaner to take the other approach (i.e. creating an all nan dataframe and then inserting the signals where needed). Either way is fine.
Thanks for the idea about Brave BAT Rewards. Thankfully, I have a very nice job, and my employer is also a very generous supporter of many open source projects, and software foundations and their conferences. Mplfinance users who want to express their appreciation financially should ideally donate to the Matplotlib fellowship.
(alternatively one can sponsor Matplotlib or make a general donation to NumFocus. Perhaps, if I have time, I'll look into whether it is possible to set up "Brave BAT Rewards" for mplfinance and have the funds sent directly to the Matplotlib fellowship).
All the best. --Daniel
Thank you. I made a second function for the other signal doing the same, adding to a different column. Have it working good now :)
Great man, and I watched your youtube video 'Pandas for Fun and Profit'. Awesome stuff.
Ok cool, thanks for the info, I'll be sure to send over some BAT if that gets setup for all the help. Once again I appreciate your time :+1:
Most helpful comment
Again, it's very difficult for me to provide an answer without seeing your code and data.
If I could see your code and data, then I could make a specific recommendation regarding your code.
Without it, I can only provide an example that is a guess as to what may be needed in your code:
... probably yes, or something like this:
mpf.make_addplot(),the length and index of
signalneeds to match the length and index being passed intompf.plot().nanvalues.```python
df_sparse = pd.DataFrame([float('nan')]*len(df),index=df.index,columns=['Signal'])
print(df_sparse)
Date
2014-09-11 NaN
2014-09-12 NaN
2014-09-15 NaN
2014-09-16 NaN
2014-09-17 NaN
2014-09-18 NaN
2014-09-19 NaN
for ix,val in zip(signal.index,signal.values):
df_sparse.loc[ix] = val
print(df_sparse)
Date
2014-09-11 NaN
2014-09-12 NaN
2014-09-15 8.700074
2014-09-16 NaN
2014-09-17 NaN
2014-09-18 9.270020
2014-09-19 NaN
```