Closed pipreaper closed 3 years ago
@pipreaper
It's difficult for me to tell because you have not shown any calls to any of the methods in the mplfinance library. Since you are calling mplfinance in external axes mode, for which you should be aware that some of the kwargs to mpf.plot()
are ignored in external axes mode: the general rule is if the kwarg involves the Figure object (to which mpf.plot()
has no access in external axes mode) or if it involves the relationship between the Axes objects and the Figure object.
From what you have written, it is also not completely clear what you are trying to accomplish: your comment says
I simply want to remove the box surrounding the figures
but the code is attempting to remove the box around the Axes (not the Figures).
Assuming the code is the ultimate documentation, try using or, alternatively, since you have control of the axes objects, you can call mpf.plot(data,...,axisoff=True)
Axes.set_axis_off()
yourself. (Correction: I just realized kwarg axisoff=True
does not work in external axes mode: as can be seen here, in external axes mode mpf.plot()
returns before the axisoff code is reached.).
If that doesn't do it for you, and you have further questions, it would be helpful if I could see the rest of your code.
All the best. --Daniel
Yes ... I see ... It is the figure I am trying to remove the bounding box/black frame from. but a call to mpf gives an interpreter error:
File "/home/rob/PycharmProjects/get_prospects/Main/Pages/Page1/Page1.py", line 412, in draw_renko self.fig_renko.spines['bottom'].set_linewidth(12.5) AttributeError: 'Mpf_Figure' object has no attribute 'spines'
when I call:
def draw_renko(self):
try:
if self.controller.show_renko:
if self.controller.renko_ohlc_show_boxes and self.controller.show_ohlc:
draw_ohlc_boxes(self, self.ohlc_axis)
self.canvas_ohlc.draw()
draw_renko_boxes(self, self.renko_axis)
self.fig_renko.suptitle(
'Renko: ' + remove(self.controller.ticker_symbol) + ', Period: ' + self.controller.interval + ' , Box Size:' + self.formatted_brick_size, fontsize=8)
self.renko_axis.axes.xaxis.set_visible(False)
self.renko_axis.set_ylabel('')
self.renko_axis.set_facecolor(chart_face_color)
self.renko_axis.tick_params(axis='y', labelsize=chart_y_font_size) # , top='off', bottom='off', left='off', right='off') # , top='off', bottom='off', left='off', right='off',
# labelleft='on', labelbottom='on')
self.renko_axis.tick_params(axis='x', labelsize=chart_y_font_size) # , top='off', bottom='off', left='off', right='off') # , labelleft='on', labelbottom='on')
# self.fig_renko.tick_params(axis='x', top='off', bottom='off', left='off', right='off')
# self.renko_axis.spines['top'].set_visible(False)
# self.renko_axis.spines['right'].set_visible(False)
# self.renko_axis.spines['left'].set_visible(False)
# self.renko_axis.spines['bottom'].set_visible(False)
# self.renko_axis.spines['bottom'].set_linewidth(2.5)
# self.renko_axis.spines['left'].set_linewidth(2.5)
# self.renko_axis.spines['bottom'].set_color('pink')
# self.renko_axis.spines['left'].set_color('pink')
# self.renko_axis.set_edge_color("white")
# self.fig_renko.set_edgecolor("white")
# self.renko_axis.set_frame_on(False)
# self.renko_axis.tick_params(top='off', bottom='off', left='off', right='off', labelleft='off', labelbottom='on')
self.fig_renko.spines['bottom'].set_linewidth(12.5)
self.fig_renko.spines['left'].set_linewidth(12.5)
self.fig_renko.spines['bottom'].set_color('blue')
self.fig_renko.spines['left'].set_color('blue')
self.canvas_renko.draw()
except Exception as e:
logger.exception(e)
How can I access spines from mpf. ? do I attempt to use kwangs is there another method?
I have code I can try and make an example but it wouldnt be any cleaner than what I have. I have attached the Page file for plot.
from tkinter import Frame
import mplfinance as mpf
import talib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from Generate_signals.RenkoSignals import RenkoBricks
from Main.FetchYahoo import get_ticker_history
from Main.Indicators.BaseIndicator import BaseIndicator
from Main.Indicators.OHLCIndicators import OHLCBaseIndicator, calc_renko_high_close
from Main.Indicators.RenkoIndicators import RenkoBaseIndicator
from Main.Pages.Page1.page1_assist_functions import *
from Main.Pages.basePage import BasePage
from Main.get_my_logger import logging
from Utilities.use_funcs import remove
from Main.defaults import chart_face_color, chart_y_font_size, chart_bounding_line_width, chart_font_axis_color, chart_outer_box_color
from styles.my_styles import my_style
logger = logging.getLogger(__name__)
class PageOne(BasePage):
def __init__(self, controller):
BasePage.__init__(self, controller, '1: Plot')
# df_ohlc = pd.DataFrame()
try:
self.last_atr = -1
self.yahoo_data = pd.DataFrame()
self.renko_data = pd.DataFrame()
# CANVASES
self.frame_canvases = None
# OHLC
self.frame_canvas_ohlc = None
self.frame_nav_ohlc = None
self.fig_ohlc = None
self.canvas_ohlc = None
self.toolbar_ohlc = None
self.ohlc_axis = None
self.ohlc_chart_loc = 0 # default for no ohlc chart displayed ... otherwise set to 1 (display)
# RENKO
self.frame_canvas_renko = None
self.frame_nav_renko = None
self.fig_renko = None
self.renko_axis = None
self.canvas_renko = None
self.toolbar_renko = None
self.kwargs_ohlc = {}
# AXIS
self.axis_list_rsi = None
self.axis_list_stochs = None
self.unique_index = None
self.x_num_index_ohlc = None
self.x_num_index_renko = None
# SUNDRY
self.my_ich = None
self.formatted_brick_size = -1
self.box_calc = -1
self.width_of_plot = -1
logger.info('initialised')
except Exception as e:
# print(e.args)
logger.exception('exception: ')
def define_layout(self):
try:
if self.frame_canvases is not None:
clear_frame(self.frame_canvases)
# create MASTER canvas frame
self.frame_canvases = Frame(self.frame_main, borderwidth=10, bg='black')
if self.controller.show_ohlc:
# create OHLC canvas frame
self.frame_canvas_ohlc = Frame(self.frame_canvases, borderwidth=10, bg='pink')
# create mpf figure
self.fig_ohlc = mpf.figure(figsize=(18, 17))
OHLCBaseIndicator.set_grid_spec(self.fig_ohlc)
# define ohlc axis
self.ohlc_axis = self.fig_ohlc.add_subplot(OHLCBaseIndicator.spec[0, 0])
# self.ohlc_axis = self.fig_ohlc.add_subplot(OHLCBaseIndicator.total_panel_rows, OHLCBaseIndicator.num_columns, 1)
# create OHLC canvas
self.canvas_ohlc = FigureCanvasTkAgg(self.fig_ohlc, self.frame_canvas_ohlc)
# toolbar OHLC
# self.frame_nav_ohlc = Frame(self.frame_canvases, borderwidth=10, bg='blue')
self.toolbar_ohlc = NavigationToolbar2Tk(self.canvas_ohlc, self.frame_canvases, pack_toolbar=False)
self.toolbar_ohlc.update()
if self.controller.show_renko:
# create a RENKO canvas frame
self.frame_canvas_renko = Frame(self.frame_canvases, borderwidth=10, bg='green')
# create a renko figure
self.fig_renko = mpf.figure(figsize=(18, 17), edgecolor=None)
RenkoBaseIndicator.set_grid_spec(self.fig_renko)
# define renko axis
self.renko_axis = self.fig_renko.add_subplot(RenkoBaseIndicator.spec[0, 0])
# self.renko_axis = self.fig_renko.add_subplot(RenkoBaseIndicator.total_panel_rows, RenkoBaseIndicator.num_columns, 1)
# create renko canvas
self.canvas_renko = FigureCanvasTkAgg(self.fig_renko, self.frame_canvas_renko)
# toolbar renko
# self.frame_nav_renko = Frame(self.frame_canvases, borderwidth=10, bg='red')
self.toolbar_renko = NavigationToolbar2Tk(self.canvas_renko, self.frame_canvases, pack_toolbar=False)
logger.info('initialised')
except Exception as e:
# print(e.args)
logger.exception('exception: ')
pass
finally:
pass
def define_position_layout(self):
# position of frame_canvases in frame_main col = 1 because menu always in 0
self.frame_canvases.grid(row=0, column=1, sticky='nsew')
row_id = -1
# decide what to plot where because navigation does not scale
if self.controller.show_ohlc and self.controller.show_renko:
self.frame_canvases.rowconfigure(0, weight=1)
self.frame_canvases.rowconfigure(2, weight=1)
self.frame_canvases.columnconfigure(0, weight=1)
elif self.controller.show_ohlc or self.controller.show_renko:
self.frame_canvases.rowconfigure(0, weight=1)
self.frame_canvases.columnconfigure(0, weight=1)
if self.controller.show_ohlc:
# create OHLC canvas frame
row_id += 1
self.frame_canvas_ohlc.grid(row=row_id, column=0, sticky='nsew')
self.frame_canvas_ohlc.rowconfigure(0, weight=1)
self.frame_canvas_ohlc.columnconfigure(0, weight=1)
# get ohlc canvas so can draw later
self.canvas_ohlc.get_tk_widget().grid(row=0, column=0)
# define nav ohlc
row_id += 1
# self.frame_nav_ohlc.grid(row=row_id, column=0, sticky='nsew')
self.toolbar_ohlc.grid(row=row_id, column=0, sticky='nsew')
if self.controller.show_renko:
# define renko canvas frame
row_id += 1
self.frame_canvas_renko.grid(row=row_id, column=0, sticky='nsew')
self.frame_canvas_renko.rowconfigure(0, weight=1)
self.frame_canvas_renko.columnconfigure(0, weight=1)
# get renko canvas so can draw later
self.canvas_renko.get_tk_widget().grid(row=0, column=0)
# define renko nav
row_id += 1
self.toolbar_renko.grid(row=row_id, column=0, sticky='nsew')
# draw canvases
# self.canvas_ohlc.draw()
# self.toolbar_ohlc.update()
# self.canvas_renko.draw()
# self.toolbar_renko.update()
def plot_me(self):
try:
set_ticker_to_plot(self)
self.define_layout()
self.define_position_layout()
self.yahoo_data = get_ticker_history(self.controller.ticker, self.controller.start, self.controller.end, self.controller.interval)
if self.yahoo_data.empty:
raise ValueError("failed to get ticker history:", self.controller.ticker_symbol, self.controller.start, self.controller.end,
self.controller.interval)
else:
OHLCBaseIndicator.add_plots = []
RenkoBaseIndicator.add_plots = []
if self.controller.interval == 'D':
self.yahoo_data = self.yahoo_data[self.yahoo_data.index.dayofweek < 5] # remove weekends but not holidays!
self.define_renko_bricks_goldfarb() # get renko associated data
self.define_ohlc_charts_data() # define chart data and indicator plots required
self.generate_renko_signals() # find double bottoms if exist
self.create_ohlc_indicators() # indicators for ohlc plot
self.draw_chart_ohlc()
self.create_main_ohlc_cursor() # create the cursors to match the required plot
self.create_ohlc_indicator_cursors() # create any cursors indicators have
self.get_high_low_renko() # get the high and low values for renko bricks to be used in renko indicators
self.create_renko_chart_indexing() # use Goldfarb bricks to define your own plot if renko required
self.create_renko_indicators() # create ichimoku ++
self.create_main_renko_cursor() # create renko cursor
self.create_renko_indicator_cursors() # create indicator cursors
self.draw_renko() # display the renko chart and indicators
except ValueError as e:
self.canvas_renko.draw()
logger.warning(e)
except Exception as e:
logger.exception(e)
def define_renko_bricks_goldfarb(self):
try:
renko_atr = (talib.ATR(self.yahoo_data['High'], self.yahoo_data['Low'], self.yahoo_data['Close'], self.controller.renko_atr_period))
# # print(df_rsi)
lst_atr = renko_atr.values.tolist()
self.last_atr = lst_atr[-1] # renko_atr.mean()
self.box_calc = self.controller.renko_box_calc * self.last_atr
self.formatted_brick_size = "BrickSize : {:.2f}".format(self.box_calc)
# check can calculate bricks
close_range = self.yahoo_data['Close'].max() - self.yahoo_data['Close'].min()
# if self.controller.ticker.strip() == 'CPG.L': logger.warning('atr period = '+str(self.controller.renko_atr_period)+' lst_atr '+str(
# self.last_atr) + ' box_calc ' + str(box_calc) + ' close range ' + str(close_range)) check for Nan in data sets
if self.box_calc >= 0.5 * close_range:
raise Exception(' Specified brick_size: ', self.formatted_brick_size,
' may not be larger than (50% of the close price range of the dataset) which has value: ', close_range)
# use Goldfarb to get the bricks then ignore:
ret_data = {}
kwargs_renko = dict(axisoff=False, xrotation=20, type='renko',
renko_params=dict(brick_size=self.box_calc), ylabel='price', tight_layout=False,
datetime_format="%d-%m-%Y", return_calculated_values=ret_data, returnfig=True, closefig=True,
ylim=(self.yahoo_data.Low.min(), self.yahoo_data.High.max()))
dum_fig, ax = mpf.plot(self.yahoo_data, **kwargs_renko, mav=[9], volume=True)
# get the class that holds the renko Bricks data
self.renko_data = RenkoBricks(self.controller.script_directory, self.controller.data_directory)
self.renko_data.set_brick_info(self.controller.ticker, ret_data, self.yahoo_data)
ax[0].cla()
# don't need Goldfarb for renko plots after have initial bricks because of issues plotting indicators viz/. Ichimoku
# dum_fig = None
except Exception as e:
logger.exception(e)
pass
def define_ohlc_charts_data(self):
"""
read yahoo series
"""
try:
# if self.controller.ticker.strip() == 'CPG.L':
# self.write_csv(self.yahoo_data, 'page1_yahoo', self.controller.script_directory, self.controller.config_directory)
self.yahoo_data = self.yahoo_data.tz_localize('UTC')
# generate the signals in the bricks df
self.yahoo_data['db_sig'] = np.nan # set signals to False
self.yahoo_data['db_low'] = np.nan
self.yahoo_data['Date'] = pd.to_datetime(self.yahoo_data.index)
except Exception as e:
logger.exception('failed to calculate the renko bricks as a function of atr: ')
def generate_renko_signals(self):
try:
if self.controller.show_renko:
if self.renko_data.Pivots.set_pivots_signal():
logger.info(' have pivots for double bottom: ')
self.renko_data.Pivots.print_pivot()
self.yahoo_data = self.renko_data.set_markers()
except Exception as e:
logger.exception('failed to create renko signals: ')
def create_ohlc_indicators(self):
"""from selected classes populate indicators"""
try:
if self.controller.show_ohlc:
# loop around indicators created creating the plots from the data
for index in range(len(OHLCBaseIndicator.indicators)):
d = OHLCBaseIndicator.indicators[index]
d.yahoo_data = self.yahoo_data
self.yahoo_data = d.my_add_plots(self)
except Exception as e:
logger.exception(e)
def draw_chart_ohlc(self):
try:
if self.controller.show_ohlc:
# my_rc ={} # {'font.size': 20}
s = mpf.make_mpf_style(base_mpf_style='charles', y_on_right=False) #, rc=my_rc)
trm = remove(self.controller.ticker_symbol)
trm = 'OHLC: ' + trm + ', Period: ' + self.controller.interval
self.fig_ohlc.suptitle(trm, fontsize=8)
self.kwargs_ohlc = dict(xrotation=20, type='candle',
ylabel='', datetime_format="%d-%m-%Y",
returnfig=True,
closefig=True)
dict(self.kwargs_ohlc, ylim=(self.yahoo_data.Low.min(), self.yahoo_data.High.max()))
if self.controller.ohlc_show_ichimoku:
fill_in = dict(y1=self.yahoo_data.senkou_span_a.values, y2=self.yahoo_data.senkou_span_b.values, alpha=1, color='black')
dict(self.kwargs_ohlc, fill_between=fill_in)
self.ohlc_axis.set_facecolor(chart_face_color)
self.ohlc_axis.tick_params(axis='y', labelsize=chart_y_font_size, colors=chart_font_axis_color)
self.ohlc_axis.tick_params(axis='x', labelsize=chart_y_font_size, colors=chart_font_axis_color)
mpf.plot(self.yahoo_data, ax=self.ohlc_axis, addplot=OHLCBaseIndicator.add_plots, **self.kwargs_ohlc)
# number index is need for the cursor position, x axis is mapped with integer first and converted to date later
self.x_num_index_ohlc = np.arange(0, len(self.yahoo_data['Close']), 1)
self.unique_index = pd.Index(self.yahoo_data.index)
self.canvas_ohlc.draw()
except Exception as e:
logger.exception(e)
def create_main_ohlc_cursor(self):
""" ohlc bar chart cursor """
try:
if self.controller.show_ohlc:
num_dec_places = 2 # set according to instrument being displayed
s_num_dec_plc = str(num_dec_places)
output_dict = {'Date': 'Date {0}\n',
'Price': 'Price {1:.' + s_num_dec_plc + 'f}\n',
'Open': 'Open {2:.' + s_num_dec_plc + 'f}\n',
'High': 'High {3:.' + s_num_dec_plc + 'f}\n',
'Low': 'Low {4:.' + s_num_dec_plc + 'f}\n',
'Close': 'Close {5:.' + s_num_dec_plc + 'f}\n'
}
create_ohlc_cursor(self, self.canvas_ohlc, self.ohlc_axis, output_dict, self.yahoo_data, self.x_num_index_ohlc, 'black', 0.5)
except Exception as e:
logger.exception(e)
def create_ohlc_indicator_cursors(self):
"""from selected classes populate cursors"""
try:
if self.controller.show_ohlc:
# loop around indicators created creating the plots from the data
for index in range(len(OHLCBaseIndicator.indicators)):
d = OHLCBaseIndicator.indicators[index]
d.create_cursor(self)
except Exception as e:
logger.exception(e)
def get_high_low_renko(self):
""" get transformed data. Needs to kn ow high and close for ichimoku renko"""
if self.controller.show_renko:
self.renko_data.bricks_df = calc_renko_high_close(self.renko_data.bricks_df, self.yahoo_data, self.renko_data.brick_size)
def create_renko_chart_indexing(self):
try:
if self.controller.show_renko:
self.x_num_index_renko = np.arange(0, len(self.renko_data.get_bricks_df()['renko_bricks_low']), 1)
except ValueError as e:
logger.warning(e)
except Exception as e:
logger.exception(e)
pass
def create_renko_indicators(self):
"""from selected classes populate renko indicators"""
try:
if self.controller.show_renko:
# loop around indicators created creating the plots from the data
for index in range(len(RenkoBaseIndicator.indicators)):
d = RenkoBaseIndicator.indicators[index]
d.renko_data = self.renko_data
self.renko_data = d.my_add_plots(self)
except Exception as e:
logger.exception(e)
def create_main_renko_cursor(self):
try:
if self.controller.show_renko:
num_dec_places = 2 # set according to instrument being displayed
s_num_dec_plc = str(num_dec_places)
output_dict = {'end_date': 'end_date {0}\n', 'renko_bricks_low': 'renko_bricks_low {1:.' + s_num_dec_plc + 'f}\n'}
renko_snap_hairs(self, self.canvas_renko, self.renko_axis, output_dict, self.renko_data.bricks_df, self.x_num_index_renko, 'black', 0.5)
except Exception as e:
logger.exception(e)
def create_renko_indicator_cursors(self):
"""from selected classes populate renko cursors"""
try:
if self.controller.show_renko:
# loop around indicators created creating the plots from the data
for index in range(len(RenkoBaseIndicator.indicators)):
d = RenkoBaseIndicator.indicators[index]
d.create_cursor(self)
except Exception as e:
logger.exception(e)
def draw_renko(self):
try:
if self.controller.show_renko:
if self.controller.renko_ohlc_show_boxes and self.controller.show_ohlc:
draw_ohlc_boxes(self, self.ohlc_axis)
self.canvas_ohlc.draw()
draw_renko_boxes(self, self.renko_axis)
self.fig_renko.suptitle(
'Renko: ' + remove(self.controller.ticker_symbol) + ', Period: ' + self.controller.interval + ' , Box Size:' + self.formatted_brick_size, fontsize=8)
self.renko_axis.axes.xaxis.set_visible(False)
self.renko_axis.set_ylabel('')
self.renko_axis.set_facecolor(chart_face_color)
self.renko_axis.tick_params(axis='y', labelsize=chart_y_font_size) # , top='off', bottom='off', left='off', right='off') # , top='off', bottom='off', left='off', right='off',
# labelleft='on', labelbottom='on')
self.renko_axis.tick_params(axis='x', labelsize=chart_y_font_size) # , top='off', bottom='off', left='off', right='off') # , labelleft='on', labelbottom='on')
# self.fig_renko.tick_params(axis='x', top='off', bottom='off', left='off', right='off')
# self.renko_axis.spines['top'].set_visible(False)
# self.renko_axis.spines['right'].set_visible(False)
# self.renko_axis.spines['left'].set_visible(False)
# self.renko_axis.spines['bottom'].set_visible(False)
# self.renko_axis.spines['bottom'].set_linewidth(2.5)
# self.renko_axis.spines['left'].set_linewidth(2.5)
# self.renko_axis.spines['bottom'].set_color('pink')
# self.renko_axis.spines['left'].set_color('pink')
# self.renko_axis.set_edge_color("white")
# self.fig_renko.set_edgecolor("white")
# self.renko_axis.set_frame_on(False)
# self.renko_axis.tick_params(top='off', bottom='off', left='off', right='off', labelleft='off', labelbottom='on')
self.fig_renko.spines['bottom'].set_linewidth(12.5)
self.fig_renko.spines['left'].set_linewidth(12.5)
self.fig_renko.spines['bottom'].set_color('blue')
self.fig_renko.spines['left'].set_color('blue')
self.canvas_renko.draw()
except Exception as e:
logger.exception(e)
hope it gives a better understanding of what Im trying to do. Any comments welcome.
How can I access spines from mpf. ? do I attempt to use kwangs is there another method?
spines are an attribute of Axes, not of Figure. The class MpfFigure is derived from Matplotlib.figure.Figure and so it does contain all of the same attributes as a matplotlib Figure. but spines is not one of them.
I will try to make time later today to look through your code and see if I have any suggestions.
Thank you. --Daniel
Hi @pipreaper I don't have time to go through your code in a lot of detail, but I did glance through it and I have a few comments that may be of some help:
First and foremost, it appears that you are mixing the ideas of returnfig
and external axes mode.
For example, I see you calling mpf.figure()
to create a figure, but elsewhere calling dum_fig, ax = mpf.plot(...,returnfig=True)
(and in draw_chart_ohlc()
you have set returnfig=True
but are altogether ignoring the Figure and Axes returned from mpf.plot()
).
Be aware that when you set returnfig=True
then mpf.plot()
will create both the FIgure and Axes objects for you and return them to you. *Those Axes objects are therefore not on the same Figure object that you have created separately with mpf.figure()
(unless you specifically add them to that Figure object yourself)*.
There is documentation here with links to additional documentaion that explain the difference between returnfig=True
and external Axes mode.
As a general rule I discourage external axes mode. You could change your code to go either way, but it is definitely not a good idea to try to mix them: The one exception (to mixing them) is when you call mpf.plot(...,returnfig=True)
once only, save the Figure and Axes list returned, and then pass those Axes back into mpf.plot()
for all subsequent calls to mpf.plot()
.
That said, looking over your code, however, I am inclined to say *I think will be easier to convert your code to use only external axes mode*. You are already saving (inside your own classes) the Figure and Axes that you created yourself with mpf.figure()
and self.fig_renko.add_subplot(RenkoBaseIndicator.spec[0, 0])
. And you are also alreading doing a lot of matplotlib manipulation of these objects anyway. You might as well use only these external Figure and Axes, and pass your Axes objects into mpf.plot()
with kwarg ax= ... maybe something like mpf.plot(...,ax=self.renko_axis,...)
.
Finally, it's still not completely clear to me which frame you are trying to eliminate. Perhaps take this image and edit it with an image editor or drawing program, placing arrows on the image pointing to the exact frame(s) you want to eliminate. It occurs to me that it is possible that some of the frames are actually part of tkinter and not necessarily part of matplotlib.
All the best.
I will work it out and post when I find solution. I think its associated with self.fig_ohlc having default rc values.
Yes so solution is to add edge color to the figures -> axes.edgecolor.
Many thanks and sorry to bother you. Just had a moment where I didn't realise that the figure had axes settings too
Hi @pipreaper I don't have time to go through your code in a lot of detail, but I did glance through it and I have a few comments that may be of some help:
First and foremost, it appears that you are mixing the ideas of
returnfig
and external axes mode. For example, I see you callingmpf.figure()
to create a figure, but elsewhere callingdum_fig, ax = mpf.plot(...,returnfig=True)
(and indraw_chart_ohlc()
you have setreturnfig=True
but are altogether ignoring the Figure and Axes returned frommpf.plot()
).Be aware that when you set
returnfig=True
thenmpf.plot()
will create both the FIgure and Axes objects for you and return them to you. Those Axes objects are therefore not on the same Figure object that you have created separately withmpf.figure()
(unless you specifically add them to that Figure object yourself).There is documentation here with links to additional documentaion that explain the difference between
returnfig=True
and external Axes mode.As a general rule I discourage external axes mode. You could change your code to go either way, but it is definitely not a good idea to try to mix them: The one exception (to mixing them) is when you call
mpf.plot(...,returnfig=True)
once only, save the Figure and Axes list returned, and then pass those Axes back intompf.plot()
for all subsequent calls tompf.plot()
.That said, looking over your code, however, I am inclined to say I think will be easier to convert your code to use only external axes mode. You are already saving (inside your own classes) the Figure and Axes that you created yourself with
mpf.figure()
andself.fig_renko.add_subplot(RenkoBaseIndicator.spec[0, 0])
. And you are also alreading doing a lot of matplotlib manipulation of these objects anyway. You might as well use only these external Figure and Axes, and pass your Axes objects intompf.plot()
with kwarg ax= ... maybe something likempf.plot(...,ax=self.renko_axis,...)
.Finally, it's still not completely clear to me which frame you are trying to eliminate. Perhaps take this image and edit it with an image editor or drawing program, placing arrows on the image pointing to the exact frame(s) you want to eliminate. It occurs to me that it is possible that some of the frames are actually part of tkinter and not necessarily part of matplotlib.
All the best.
Thank you so much for taking the time to look at the code.
wrt your comments:
1/. I use dum_fig, ax = mpf.plot(...,returnfig=True) to return mplfinance volume and brick information but do not want to plot it as (rightly or wrongly), I needed more control over the axis for cursor manipulation and indicator plotting (could not see a way to use fill with mplfinance to get different colors I wanted to see on Ichimoku). Returning a fig and an axis that I was never going to use was the only way I could see to do this whilst having the convenience of not having to calculate the volume and brick information by other means. I also pull this same information for many instruments when looping around the algo for instrument selection .... If there is another way of getting your information on bricks and volume whilst using my own external axes I would be grateful to know it so please advise.
2/. Yes I see what I was doing in draw_chart_ohlc was incorrect. Many thanks. I have now removed returnfig=True, closefig=True from the kwarg list past to the mpf.plot(...).
3/. What I was trying to do ... please see explanation above. where the axes are now bounded in blue with the code changes highlighted in the code editor.
I have used mplfinance to develop a front end for a instrument search algo.
I have used your code to generate bricks from renko but ended up going to external axis mode since I am interested in Icimoku cloud fill.
I simply want to remove the box surrounding the figures or at least change its color. I am confused since some parameters I pass as kwargs to plot work and some just do not. However I would have expected the following code to hide the box outline. It does not. Is something in mplfinance overrriding these settings. Other axis settings in the example code work well.
Example Code.
I see you are doing a good job of the project but the documentation around this area is sketchy? Sure there is an easy explanation i just cant bottom it right now. Any ideas welcome