用mplfinance在一个循环里画K线图,代码如下:
re_mpf(df_stock,type='candle', mav=(10, 20), volume=True, datetime_format='', figsize=(25, 8), style='charles', ylabel='', ylabel_lower='', savefig=path_list[biao]+re_name)
这里re_mpf=mpf.plot。
1.如果要有返回则加参数returnfig=True,返回两个数据:fig,axes。
2.如果没有savefig参数,则运行完该方法直接在屏幕上画K线出来。
3.循环函数运行时内存的使用量不断增加,用memory_profiler查看是该方法出了问题,在其他方面也验证了是该方法出了问题。是不是文件句柄没有关闭引起的?但不应该犯这种错误,看mplfinance模块源代码,它的savefig是调用matplotlib.pyplot的,而pyplot又是调用finger里面的savefig,里面的相关代码是带with维护上下文的,所以应该不是文件句柄的原因。第二天看matplotlib官网的讨论群(英文的,边翻译边看),也有说到savefig使内存不断增长这个问题,里面官方回复说是用的backend的问题,回来后通过plt.get_backend()查看我电脑上的backend是GTK3gg,而matplotlib的finger模块代码里面建议用"cairo",开始把前面re_mpf方法里面的savefig参数换成字典参数(看过源代码,是支持的),增加"backend":"cairo",但不起作用,应该是matplotlib的finger模块的savefig方法没有backend这个参数,所以不起作用。再看matplotlib.pyplot,有一个switch_backend方法:
plt.switch_backend('cairo')
再次运行re_mpf(),内存不再继续增加,通过plt.get_backend()查看backend已经是"cairo"。
4.如果需要增加其他参数,最好看mplfinance源代码前面就是参数的说明,网上有用的信息太少了,大多是复制粘贴的,浪费时间。
现复制源代码关于参数的验证方法,可以加深对相关参数的理解,注意这是个私有方法。
def _valid_plot_kwargs():
'''
Construct and return the "valid kwargs table" for the mplfinance.plot() function.
A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are the
valid key-words for the function. The value for each key is a dict containing
2 specific keys: "Default", and "Validator" with the following values:
"Default" - The default value for the kwarg if none is specified.
"Validator" - A function that takes the caller specified value for the kwarg,
and validates that it is the correct type, and (for kwargs with
a limited set of allowed values) may also validate that the
kwarg value is one of the allowed values.
'''
vkwargs = {
'columns' : { 'Default' : None, # use default names: ('Open', 'High', 'Low', 'Close', 'Volume')
'Validator' : lambda value: isinstance(value, (tuple, list))
and len(value) == 5
and all(isinstance(c, str) for c in value) },
'type' : { 'Default' : 'ohlc',
'Validator' : lambda value: value in _get_valid_plot_types() },
'style' : { 'Default' : None,
'Validator' : _styles._valid_mpf_style },
'volume' : { 'Default' : False,
'Validator' : lambda value: isinstance(value,bool) or isinstance(value,mpl_axes.Axes) },
'mav' : { 'Default' : None,
'Validator' : _mav_validator },
'renko_params' : { 'Default' : dict(),
'Validator' : lambda value: isinstance(value,dict) },
'pnf_params' : { 'Default' : dict(),
'Validator' : lambda value: isinstance(value,dict) },
'study' : { 'Default' : None,
'Validator' : lambda value: _kwarg_not_implemented(value) },
'marketcolors' : { 'Default' : None, # use 'style' for default, instead.
'Validator' : lambda value: isinstance(value,dict) },
'no_xgaps' : { 'Default' : True, # None means follow default logic below:
'Validator' : lambda value: _warn_no_xgaps_deprecated(value) },
'show_nontrading' : { 'Default' : False,
'Validator' : lambda value: isinstance(value,bool) },
'figscale' : { 'Default' : None, # scale base figure size up or down.
'Validator' : lambda value: isinstance(value,float) or isinstance(value,int) },
'figratio' : { 'Default' : None, # aspect ratio; scaled to 8.0 height
'Validator' : lambda value: isinstance(value,(tuple,list))
and len(value) == 2
and isinstance(value[0],(float,int))
and isinstance(value[1],(float,int)) },
'figsize' : { 'Default' : None, # figure size; overrides figratio and figscale
'Validator' : lambda value: isinstance(value,(tuple,list))
and len(value) == 2
and isinstance(value[0],(float,int))
and isinstance(value[1],(float,int)) },
'fontscale' : { 'Default' : None, # scale all fonts up or down
'Validator' : lambda value: isinstance(value,float) or isinstance(value,int) },
'linecolor' : { 'Default' : None, # line color in line plot
'Validator' : lambda value: mcolors.is_color_like(value) },
'title' : { 'Default' : None, # Figure Title
'Validator' : lambda value: isinstance(value,(str,dict)) },
'axtitle' : { 'Default' : None, # Axes Title (subplot title)
'Validator' : lambda value: isinstance(value,(str,dict)) },
'ylabel' : { 'Default' : 'Price', # y-axis label
'Validator' : lambda value: isinstance(value,str) },
'ylabel_lower' : { 'Default' : None, # y-axis label default logic below
'Validator' : lambda value: isinstance(value,str) },
'addplot' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,dict) or (isinstance(value,list) and all([isinstance(d,dict) for d in value])) },
'savefig' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,dict) or isinstance(value,str) or isinstance(value, io.BytesIO) },
'block' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,bool) },
'returnfig' : { 'Default' : False,
'Validator' : lambda value: isinstance(value,bool) },
'return_calculated_values' : {'Default' : None,
'Validator' : lambda value: isinstance(value, dict) and len(value) == 0},
'set_ylim' : {'Default' : None,
'Validator' : lambda value: _warn_set_ylim_deprecated(value) },
'ylim' : {'Default' : None,
'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2
and all([isinstance(v,(int,float)) for v in value])},
'xlim' : {'Default' : None,
'Validator' : lambda value: _xlim_validator(value) },
'set_ylim_panelB' : {'Default' : None,
'Validator' : lambda value: _warn_set_ylim_deprecated(value) },
'hlines' : { 'Default' : None,
'Validator' : lambda value: _hlines_validator(value) },
'vlines' : { 'Default' : None,
'Validator' : lambda value: _vlines_validator(value) },
'alines' : { 'Default' : None,
'Validator' : lambda value: _alines_validator(value) },
'tlines' : { 'Default' : None,
'Validator' : lambda value: _tlines_validator(value) },
'panel_ratios' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,(tuple,list)) and len(value) <= 10 and
all([isinstance(v,(int,float)) for v in value]) },
'main_panel' : { 'Default' : 0,
'Validator' : lambda value: _valid_panel_id(value) },
'volume_panel' : { 'Default' : 1,
'Validator' : lambda value: _valid_panel_id(value) },
'num_panels' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,int) and value in range(1,10+1) },
'datetime_format' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,str) },
'xrotation' : { 'Default' : 45,
'Validator' : lambda value: isinstance(value,(int,float)) },
'axisoff' : { 'Default' : False,
'Validator' : lambda value: isinstance(value,bool) },
'closefig' : { 'Default' : 'auto',
'Validator' : lambda value: isinstance(value,bool) },
'fill_between' : { 'Default' : None,
'Validator' : lambda value: _num_or_seq_of_num(value) or
(isinstance(value,dict) and 'y1' in value and
_num_or_seq_of_num(value['y1'])) },
'tight_layout' : { 'Default' : False,
'Validator' : lambda value: isinstance(value,bool) },
'width_adjuster_version' : { 'Default' : 'v1',
'Validator' : lambda value: value in ('v0', 'v1') },
'scale_width_adjustment' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,dict) and len(value) > 0 },
'update_width_config' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,dict) and len(value) > 0 },
'return_width_config' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,dict) and len(value)==0 },
'saxbelow' : { 'Default' : True, # Issue#115 Comment#639446764
'Validator' : lambda value: isinstance(value,bool) },
'scale_padding' : { 'Default' : 1.0, # Issue#193
'Validator' : lambda value: _scale_padding_validator(value) },
'ax' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,mpl_axes.Axes) },
'volume_exponent' : { 'Default' : None,
'Validator' : lambda value: isinstance(value,int) or value == 'legacy'},
'tz_localize' : { 'Default' : True,
'Validator' : lambda value: isinstance(value,bool) },
'yscale' : { 'Default' : None,
'Validator' : lambda value: _yscale_validator(value) },
'volume_yscale' : { 'Default' : None,
'Validator' : lambda value: _yscale_validator(value) },
'warn_too_much_data' : { 'Default' : 599,
'Validator' : lambda value: isinstance(value,int) },
}
_validate_vkwargs_dict(vkwargs)
return vkwargs