[PYTHON] Je souhaite résoudre le problème de fuite de mémoire lors de la sortie d'un grand nombre d'images avec Matplotlib

Aperçu

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.

Environnement d'exploitation

Python:3.7.7 Matplotlib:3.2.2

Enquête

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.

graph2.PNG

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 vas-tu faire?

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()

graph.PNG

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

Je souhaite résoudre le problème de fuite de mémoire lors de la sortie d'un grand nombre d'images avec Matplotlib
Lors de la génération d'un grand nombre de graphiques avec matplotlib, je ne souhaite pas afficher le graphique à l'écran (environnement jupyter)
Je voulais résoudre le problème ABC164 A ~ D avec Python
TensorFlow Pour apprendre d'un grand nombre d'images ... (Problème non résolu) → 12/18 Résolu
Je souhaite créer manuellement une légende avec matplotlib
J'ai essayé de résoudre le problème avec Python Vol.1
Le 15e temps réel hors ligne, j'ai essayé de résoudre le problème de l'écriture avec python
J'ai essayé de résoudre le problème d'optimisation des combinaisons avec Qiskit
J'ai essayé de résoudre le problème de F02 comment écrire en temps réel hors ligne avec Python
[Introduction à StyleGAN] J'ai joué avec "The Life of a Man" ♬
Essayez de résoudre le problème N Queen avec SA de PyQUBO
Je veux sortir le début du mois prochain avec Python
Je veux vérifier la position de mon visage avec OpenCV!
[Django] Que faire quand il y a de nombreux champs dans le modèle que vous souhaitez créer
Gérez le chevauchement lors du dessin d'un diagramme de dispersion avec une grande quantité de données (Matplotlib, Pandas, Datashader)
Je veux créer un graphique avec des lignes ondulées au milieu avec matplotlib (je veux manipuler l'impression)
J'ai essayé de prédire le nombre de personnes infectées au niveau national de la nouvelle corona avec un modèle mathématique
Une histoire dans laquelle l'algorithme est arrivé à une conclusion ridicule en essayant de résoudre correctement le problème du voyageur de commerce
Comment écrire quand on veut mettre un nombre après le numéro de groupe à remplacer par une expression régulière dans re.sub de Python
Je souhaite générer une sortie lors de la conversion de la valeur du type (par exemple, datetime) qui n'est pas pris en charge lors de la sortie de json avec python
Vous voulez résoudre un problème de classification simple?
(Matplotlib) Je veux dessiner un graphique avec une taille spécifiée en pixels
Je souhaite trier une liste dans l'ordre des autres listes
Je veux exprimer mes sentiments avec les paroles de Mr. Children
Signifie mémo lorsque vous essayez de faire de l'apprentissage automatique avec 50 images
Je souhaite arrêter la suppression automatique de la zone tmp dans RHEL7
Essayez de résoudre un problème défini de mathématiques au lycée avec Python
Python: je souhaite mesurer proprement le temps de traitement d'une fonction
Je veux afficher le nombre de num_boost_round lorsque early_stopping est appliqué à l'aide du rappel XGBoost (non atteint)
Je veux faire de matplotlib un thème sombre
Essayez de résoudre le problème du fizzbuzz avec Keras
Essayez de résoudre le problème du voyageur de commerce avec un algorithme génétique (code Python)
[AtCoder] Résoudre un problème de ABC101 ~ 169 avec Python
Je souhaite afficher uniquement différentes lignes du fichier texte avec diff
Je veux faire un jeu avec Python
Notez la solution car django n'a pas pu s'installer avec pip
Je souhaite définir un cycle de vie dans la définition de tâche d'ECS
Je veux ajouter du silence pendant 1 seconde au début d'un fichier wav
Je souhaite voir une liste de fichiers WebDAV dans le module Requêtes
Je veux résoudre APG4b avec Python (chapitre 2)
Je souhaite personnaliser l'apparence de zabbix
Je veux écrire dans un fichier avec Python
Je voulais connaître le nombre de lignes dans plusieurs fichiers et j'ai essayé de l'obtenir avec une commande
J'ai essayé de créer un modèle avec l'exemple d'Amazon SageMaker Autopilot
J'ai essayé de faire quelque chose comme un chatbot avec le modèle Seq2Seq de TensorFlow
[Python] Je souhaite utiliser uniquement l'index lors de la mise en boucle d'une liste avec une instruction for
Comment identifier l'élément avec le plus petit nombre de caractères dans une liste Python?
J'ai essayé de résoudre le problème d'optimisation du placement de la machine virtuelle (version simple) avec blueqat
Je veux tracer les informations de localisation de GTFS Realtime sur Jupyter! (Avec ballon)
Je voulais collecter beaucoup d'images, j'ai donc essayé d'utiliser "google image download"
Lorsque la variable que vous souhaitez utiliser comme exposant dans matplotlib comporte deux caractères ou plus
Un mémo sur la façon de surmonter le problème difficile de la capture d'effets avec l'IA
Une note de malentendu lors de la tentative de chargement de l'intégralité du module self-made avec Python3
Je souhaite être informé de l'environnement de connexion lorsque RaspberryPi se connecte au réseau
Accélérez un grand nombre de requêtes simples dans MySQL
Je veux détecter des images de chats d'Instagram