I am using mplfinance to create a OHLC chart (stock prices)
This is implemented as a custom class as I need to add additional elements to the final chart
class CandlestickChart:
def __init__(self, data):
self.data = data
self.fig, self.ax = mpf.plot(
self.data,
type="ohlc",
volume=False,
returnfig=True,
)
I then have another function that
def add_swap_zone(self, swap_zone):
zone_data = self.data.copy()
zone_data["in_swap_zone"] = (zone_data.index >= swap_zone.x_left) & (
zone_data.index <= swap_zone.x_right
)
zone_data["swap_zone_val"] = np.nan
zone_data.loc[zone_data["in_swap_zone"], "swap_zone_val"] = swap_zone.y_down
zone_data["swap_zone_val"].fillna(swap_zone.y_up, inplace=True)
ap_swap_zone = mpf.make_addplot(
zone_data["swap_zone_val"],
type="bar",
width=0.5,
color=swap_zone.style.FILL_COLOUR,
alpha=swap_zone.style.FILL_ALPHA,
panel=0,
secondary_y=False,
)
self.ax[0].add_artist(ap_swap_zone)
While the mechanics of the function may look complex, in essence I am using mpf.make_addplot to create a new plot, which then gets added to self.ax[0]
The error I receive is
Traceback (most recent call last):
File "/Users/user/projects/charter/src/draw/demo/demo_plot.py", line 42, in <module>
main()
File "/Users/user/projects/charter/src/draw/demo/demo_plot.py", line 35, in main
cs_chart.add_swap_zone(
File "/Users/user/projects/charter/src/draw/plot.py", line 39, in add_swap_zone
self.ax[0].add_artist(ap_swap_zone)
File "/Users/user/projects/charter/venv/lib/python3.11/site-packages/matplotlib/axes/_base.py", line 2219, in add_artist
a.axes = self
^^^^^^
AttributeError: 'dict' object has no attribute 'axes'
I have tried the below alternative ways to add the plot and still failed
self.ax[list(self.ax.keys())[0]].add_artist(ap_swap_zone)self.ax["0"].add_artist(ap_swap_zone)
EDIT: Revised code based on selected answer
class CandlestickChart:
def __init__(self, data):
self.data = data
self.addplot_specs = []
def add_swap_zone(self, swap_zone):
zone_data = self.data.copy()
zone_data["in_swap_zone"] = (zone_data.index >= swap_zone.x_left) & (
zone_data.index <= swap_zone.x_right
)
zone_data["swap_zone_val"] = np.nan
zone_data.loc[zone_data["in_swap_zone"], "swap_zone_val"] = swap_zone.y_down
zone_data["swap_zone_val"].fillna(swap_zone.y_up, inplace=True)
ap_swap_zone = mpf.make_addplot(
zone_data["swap_zone_val"],
type="bar",
width=0.5,
color=swap_zone.style.FILL_COLOUR,
alpha=swap_zone.style.FILL_ALPHA,
panel=0,
secondary_y=False,
)
self.addplot_specs.append(ap_swap_zone)
def plot(self):
self.fig, self.ax = mpf.plot(
self.data,
type="ohlc",
volume=False,
returnfig=True,
addplot=self.addplot_specs,
)
mpf.show()
Constructor initialises self.addplot_specs[] which is then appended with addplot specification in add_swap_zone(). The mpl.plot() passes addplot=self.addplot_specs
Your problem is that
mpf.make_addplot()does not return a matplotlibArtistobject.Rather,
mpf.make_addplot()returns an "addplotspecification object" which can then be passed into theaddplot=kwarg ofmpf.plot()(alternatively one can also assign a
listof such "addplotspecification" objects to theaddplot=kwarg).You should rearrange you code accordingly to first build the list of one or more
make_addplot()objects (inside yourCandlestickChartobject), and then callmpf.plot().Thus the
CandlestickChartconstructor should not callmpf.plot()but rather create a method on the class that will callmpf.plot()when you are ready.(Or alternatively the constructor can call
mpf.plot()but only if it has all of the addplot specification objects at the time of construction).Let me know if that answers your question or if you need any additional information.
(P.S. Just fyi, the reason you are getting an error messsage about a
dictis because, for the time being, theaddplotspecification object is adict, however this is not always guaranteed to be the case. It could be that some day in the future mplfinance will have a need to define its own class for theaddplotspecification object, which is why mplfinance users should not manipulate thisdicton their own but rather only usempf.make_addplot()to build it.)