使用 mplfinance/matplotlib 时可能会发生内存泄漏。如何解决?
Possible memory leak when using mplfinance/matplotlib. How to solve it?
我正在尝试为 CNN 制作大量(约 170 万)图像(带成交量的烛台图)。但是,据我所知,我目前拥有的脚本在每次迭代后不断增加其内存使用量,每次迭代大约 2-5mb。这会增加,直到我的内存完全填满,无论我有多少实例 运行ning 脚本。 (其中 16gb,脚本最终使用了 11-12gb)。
目标是同时 运行 脚本的多个实例。我尝试了并行处理,但结果并不理想。因此,我只是使用多个内核。我尝试了很多减少内存使用的方法,但似乎没有任何效果。
我在 VS 代码中使用 Jupyter notebooks (Python 3.8.5) (anaconda),有一个 64 位 Windows 系统。 16GB 内存和第 8 代 Intel i7。
首先 Cell 调用包、加载数据并设置参数。
# import required packages
import matplotlib.dates as mpdates
import matplotlib.pyplot as plt
import mplfinance as mpf
import matplotlib as mpl
from PIL import Image
import pandas as pd
import math as math
import numpy as np
import io as io
import gc as gc
import os as os
#set run instance number
run=1
#timeframe
tf = 20
#set_pixels
img_size=56
#colors
col_up = '#00FF00'
col_down = '#FF0000'
col_vol = "#0000FF"
#set directory
direct = "C:/Users/robin/1 - Scriptie/images/"
#loading the data
data1 = pd.read_csv(r'D: - School\Econometrics20 - 2021\Scriptie\Explainable AI\Scripts\Data\test_data.csv',header=[0, 1] , index_col = 0 )
data1.index=pd.to_datetime(data1.index)
#subsetting the data
total_symbols = math.floor(len(data1.columns.unique(level=0))/6)
symbols1 = data1.columns.unique(level=0)[(run-1)*total_symbols:run*total_symbols]
#set the plot parameters
mc = mpf.make_marketcolors(up = col_up ,down = col_down, edge='inherit', volume= col_vol, wick='inherit')
s = mpf.make_mpf_style(marketcolors=mc)
第二个单元格定义用于绘制图表的函数:
# creating candlestick chart with volume
def plot_candle(i,j,data,symbols,s,mc,direct,img_size, tf):
#slicing data into 30 trading day windows
data_temp=data[symbols[j]][i-tf:i]
#creating and saving the candlestick charts
buf = io.BytesIO()
save = dict(fname= buf, rc = (["boxplot.whiskerprops.linewidth",10]),
pad_inches=0,bbox_inches='tight')
mpf.plot(data_temp,savefig=save, type='candle',style=s, volume=True, axisoff=True,figratio=(1,1),closefig=True)
buf.seek(0)
im = Image.open(buf).resize((img_size,img_size))
im.save(direct+"/"+str(symbols[j])+"/"+str(i-tf+1)+".png", "PNG")
buf.close()
plt.close("all")
第三个单元格遍历数据并调用第二个单元格中的函数。
#check if images folder excists, if not, create it.
if not os.path.exists(direct):
os.mkdir("C:/Users/robin/1 - Scriptie/images")
for j in range(0,len(symbols1)):
#Check if symbol folder excists, if not, create it
if not os.path.exists(direct+"/"+symbols1[j]):
os.mkdir(direct + "/"+symbols1[j])
for i in range(tf,len(data1)) :
#check if the file has already been created
if not os.path.exists(direct+"/"+str(symbols1[j])+"/" +str(i-tf+1)+".png"):
#call the functions and create the
plot_candle(i , j , data1 , symbols1 ,s ,mc ,direct , img_size, tf)
gc.collect()
通过评论进行推广:
问题在于,默认情况下 Matplotlib 会尝试使用基于 GUI 的后端(它正在为每个绘图创建一个 GUI window)。当您关闭它们时,我们会拆掉我们这边的东西,并告诉 GUI 拆掉它(基于 C++ 的)那面的东西。然而,这种拆卸发生在 GUI 事件循环上,在这种情况下它永远不会 运行,因此 c++ 端对象在“即将被删除”状态下累积,直到它 运行 停止内存。
通过将后端设置为 'agg'
,我们根本不会尝试制作任何 GUI windows,因此没有 GUI 对象可以拆除(最好的优化是不做这件事; ))。我希望它在墙上的时间也能稍微快一点(因为再一次,不要做你不需要做的工作!)。
有关 GUI 集成的工作原理,请参阅 https://matplotlib.org/tutorials/introductory/usage.html#backends for more details on backends, see https://matplotlib.org/users/interactive.html 和其中的链接。
我正在尝试为 CNN 制作大量(约 170 万)图像(带成交量的烛台图)。但是,据我所知,我目前拥有的脚本在每次迭代后不断增加其内存使用量,每次迭代大约 2-5mb。这会增加,直到我的内存完全填满,无论我有多少实例 运行ning 脚本。 (其中 16gb,脚本最终使用了 11-12gb)。
目标是同时 运行 脚本的多个实例。我尝试了并行处理,但结果并不理想。因此,我只是使用多个内核。我尝试了很多减少内存使用的方法,但似乎没有任何效果。
我在 VS 代码中使用 Jupyter notebooks (Python 3.8.5) (anaconda),有一个 64 位 Windows 系统。 16GB 内存和第 8 代 Intel i7。
首先 Cell 调用包、加载数据并设置参数。
# import required packages
import matplotlib.dates as mpdates
import matplotlib.pyplot as plt
import mplfinance as mpf
import matplotlib as mpl
from PIL import Image
import pandas as pd
import math as math
import numpy as np
import io as io
import gc as gc
import os as os
#set run instance number
run=1
#timeframe
tf = 20
#set_pixels
img_size=56
#colors
col_up = '#00FF00'
col_down = '#FF0000'
col_vol = "#0000FF"
#set directory
direct = "C:/Users/robin/1 - Scriptie/images/"
#loading the data
data1 = pd.read_csv(r'D: - School\Econometrics20 - 2021\Scriptie\Explainable AI\Scripts\Data\test_data.csv',header=[0, 1] , index_col = 0 )
data1.index=pd.to_datetime(data1.index)
#subsetting the data
total_symbols = math.floor(len(data1.columns.unique(level=0))/6)
symbols1 = data1.columns.unique(level=0)[(run-1)*total_symbols:run*total_symbols]
#set the plot parameters
mc = mpf.make_marketcolors(up = col_up ,down = col_down, edge='inherit', volume= col_vol, wick='inherit')
s = mpf.make_mpf_style(marketcolors=mc)
第二个单元格定义用于绘制图表的函数:
# creating candlestick chart with volume
def plot_candle(i,j,data,symbols,s,mc,direct,img_size, tf):
#slicing data into 30 trading day windows
data_temp=data[symbols[j]][i-tf:i]
#creating and saving the candlestick charts
buf = io.BytesIO()
save = dict(fname= buf, rc = (["boxplot.whiskerprops.linewidth",10]),
pad_inches=0,bbox_inches='tight')
mpf.plot(data_temp,savefig=save, type='candle',style=s, volume=True, axisoff=True,figratio=(1,1),closefig=True)
buf.seek(0)
im = Image.open(buf).resize((img_size,img_size))
im.save(direct+"/"+str(symbols[j])+"/"+str(i-tf+1)+".png", "PNG")
buf.close()
plt.close("all")
第三个单元格遍历数据并调用第二个单元格中的函数。
#check if images folder excists, if not, create it.
if not os.path.exists(direct):
os.mkdir("C:/Users/robin/1 - Scriptie/images")
for j in range(0,len(symbols1)):
#Check if symbol folder excists, if not, create it
if not os.path.exists(direct+"/"+symbols1[j]):
os.mkdir(direct + "/"+symbols1[j])
for i in range(tf,len(data1)) :
#check if the file has already been created
if not os.path.exists(direct+"/"+str(symbols1[j])+"/" +str(i-tf+1)+".png"):
#call the functions and create the
plot_candle(i , j , data1 , symbols1 ,s ,mc ,direct , img_size, tf)
gc.collect()
通过评论进行推广:
问题在于,默认情况下 Matplotlib 会尝试使用基于 GUI 的后端(它正在为每个绘图创建一个 GUI window)。当您关闭它们时,我们会拆掉我们这边的东西,并告诉 GUI 拆掉它(基于 C++ 的)那面的东西。然而,这种拆卸发生在 GUI 事件循环上,在这种情况下它永远不会 运行,因此 c++ 端对象在“即将被删除”状态下累积,直到它 运行 停止内存。
通过将后端设置为 'agg'
,我们根本不会尝试制作任何 GUI windows,因此没有 GUI 对象可以拆除(最好的优化是不做这件事; ))。我希望它在墙上的时间也能稍微快一点(因为再一次,不要做你不需要做的工作!)。
有关 GUI 集成的工作原理,请参阅 https://matplotlib.org/tutorials/introductory/usage.html#backends for more details on backends, see https://matplotlib.org/users/interactive.html 和其中的链接。