Il n'est pas rare d'utiliser Matplotlib pour visualiser des données et des images de sortie. À ce moment-là, si vous sortez une image à l'aide de savefig, une légère fuite de mémoire semble se produire. Il n'y a pas de problème particulier si le nombre d'images est de plusieurs centaines à plusieurs milliers, mais cela devient un problème lorsque l'on souhaite produire des dizaines de milliers à des centaines de milliers d'images pendant une nuit pour une quantité considérablement importante de données.
Python:3.7.7 Matplotlib:3.2.2
J'ai vérifié la quantité d'augmentation de mémoire en utilisant le code suivant.
import os
import numpy as np
import datetime as dt
import matplotlib.pyplot as plt
import psutil
#Données pour la mesure
memory_start = psutil.virtual_memory().used
time_start = dt.datetime.now()
fw = open('./Journal de mesure.csv','w')
fw.write('i,time_delta[s],memory[KB]\n')
#Sortie 10 000 feuilles
for i in range(10000):
#Générer deux types de données
size = 10000
x1 = np.random.randn(size)
y1 = 0.5*x1 + 0.5**0.5*np.random.randn(size)
x2 = np.random.randn(size)
y2 = np.random.randn(size)
#Initialisez le graphique et créez un diagramme de dispersion
fig, ax = plt.subplots(figsize=(8,8))
ax.scatter(x1, y1, alpha=0.1, color='r', label='data1')
ax.scatter(x2, y2, alpha=0.1, color='g', label='data2')
#Ajouter des étiquettes et des légendes
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.legend(loc='upper right')
#Sortie d'image
plt.savefig('./output/{:05}.png'.format(i))
#Publier les données du graphique *
#plt.clf()
#plt.cla()
plt.close()
#Mesurez l'augmentation de la mémoire depuis le début et le temps d'une boucle
memory_delta = psutil.virtual_memory().used - memory_start
time_end = dt.datetime.now()
time_delta = time_end - time_start
time_start = time_end
fw.write('{},{},{}\n'.format(i+1, time_delta.microseconds/1e6, memory_delta/1e3))
fw.close()
Lors de la libération de la mémoire du graphe, il a été mesuré lorsque seule la fermeture était effectuée et lorsque cla et clf étaient exécutés puis fermés.
L'augmentation de la mémoire est réduite à environ la moitié lorsque cla et clf sont exécutés avant le cas de la fermeture uniquement. Cependant, il peut être confirmé qu'il augmente dans les deux cas.
Que dois-je faire pour éviter que la mémoire n'augmente, quel que soit le nombre d'images produites? À la suite de divers essais, la fuite de mémoire a été supprimée en réécrivant le code comme suit. J'ai pu sortir l'image correctement.
#Initialiser une seule fois au début
fig, ax = plt.subplots(figsize=(8,8))
for i in range(10000):
#Générer deux types de données
x1 = np.random.randn(size)
y1 = 0.5*x1 + 0.5**0.5*np.random.randn(size)
x2 = np.random.randn(size)
y2 = np.random.randn(size)
ax.scatter(x1, y1, alpha=0.1, color='r', label='data1')
ax.scatter(x2, y2, alpha=0.1, color='g', label='data2')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.legend(loc='upper right')
plt.savefig('./output/{:05}.png'.format(i))
#Ne fais que cla
#clf,Si vous le fermez, vous ne pourrez plus écrire sur le graphique après cela.
#Au contraire, si vous n'effectuez pas cla, cela se superposera de plus en plus à l'image précédente.
plt.cla()
Si vous ne voulez pas changer la taille de l'image au milieu, je pense que n'importe quel graphique peut être manipulé avec cela, mais je n'en suis pas si sûr, alors soyez prudent lorsque vous l'utilisez.
Recommended Posts