pythonpandasmatplotlibmplfinance

How to plot multiple markers in mplfinance scatter plot


I am using pandas v 1.5.3 and Python 3.10.

I have timeseries data along with flag columns like this:

                Open        High         Low       Close   Adj Close    Volume    Flag                                              
Date                                                                                                                                          
2018-01-10  155.745697  157.103256  155.353729  156.959854  122.008064   4366109               1                                              
2018-01-12  156.806885  157.495224  155.860428  155.965576  121.235191   5263367               3                                              
2018-01-22  154.407272  156.768646  154.024857  155.449326  120.833931   8870917               1                                              
2018-02-06  143.680695  148.652008  142.552582  148.508606  115.438744  10321614               8                                              
2018-02-09  142.065002  143.919693  138.049713  142.934998  112.200180   8188402               1      

Here are the data types of the columns in the dataframe.

Open              float64                                                                                                                     
High              float64                                                                                                                     
Low               float64                                                                                                                     
Close             float64
Adj Close         float64
Volume              int64
Flag                int64

This is the index type:

Index dtype
datetime64[ns]

I want to use the flag number to determine the type of symbol to plot on the chart (a simple mapping from my boolean flag to a matplotlib marker symbol to use on the chart).

This is what I have so far (only relevant part shown):

# Define the plot style
ohlc_style = mpf.make_mpf_style(base_mpf_style='charles',
                                y_on_right=False,
                                marketcolors=mpf.make_marketcolors(up='g', down='r'),
                                mavcolors=['purple', 'orange'],
                                figcolor='w')

# Plot the chart with the 'Flag' as scatter points
mpf.plot(df, type='candle', style=ohlc_style, volume=True, show_nontrading=False, addplot=df['Flag'], scatter=True)

However, when I run this, it raises the following exception:

raise TypeError('kwarg "'+key+'" validator returned False for value: "'+str(value)+'"\n    '+v)
TypeError: kwarg "addplot" validator returned False for value: "Date
2018-01-02    0
2018-01-03    0
2018-01-04    0
2018-01-05    0
2018-01-08    0
             ..
2021-12-27    0
2021-12-28    0
2021-12-29    0
2021-12-30    0
2021-12-31    0
Name: Flag, Length: 1008, dtype: int64"
    'Validator'   : lambda value: isinstance(value,dict) or (isinstance(value,list) and all([isinstance(d,dict) for d in value])) },

How do I fix this error, and also to use a mapping function that uses a hardocded map to map from my flag integers to a matplotlib.markers style?


Solution

  • As mentioned by @Corralien you cannot pass data directly to the addplot= kwarg, but rather you must call mpf.make_addplot() to generate and "addplot object" to pass as the value of the addplot= kwarg.

    In addition to this, to have multiple scatter markers, do the following:

    When calling mpf.make_addplot() set kwarg marker= to a list (or tuple) of markers (instead of a single marker value).

    For some examples, click here.

    Note that if marker= is not a single marker, then it must contain the same number of markers that the data frame contains rows.

    Note also (as you can see in the examples) kwarg color= may also be either a single color, or a list or tuple of colors: If a list or tuple, then again it must contain the same number of elements as the data frame contains rows.