Lors de la reconnaissance d'images sur jupyter, vous souhaiterez peut-être organiser de nombreuses images et graphiques. Affichez toutes les images des enseignants MNIST. (Si tu le fais vraiment, tu ne reviendras pas et je pense que ça va tomber)
show_mnist_NG.py
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import keras
mnist = keras.datasets.mnist.load_data()
(X_train, t_train), (X_test, t_test) = mnist
f, ax = plt.subplots(3000,20, figsize=(20,3000))
axes = ax.reshape((-1,))
for x, ax in zip(X_train, axes):
ax.imshow(x, cmap=cm.gray)
ax.axis('equal')
ax.axis('off')
plt.show()
Cependant, il devenait ennuyeux d'appeler matplotlib chaque fois que je dessinais un graphique ou une image. Par conséquent, j'ai créé un mécanisme pour l'afficher sans autorisation.
matplotlib.pyplot.subplots()
Utilisez subplots () pour organiser les images et les graphiques.
subplots_rowcol.py
import matplotlib.pyplot as plt
nrows = 3
ncols = 5
f, axes = plt.subplots(nrows, ncols, squeeze=False, figsize=(ncols*2.0, nrows*2.0))
for i in range(13):
r = i // ncols
c = i % ncols
axes[r,c].plot(range(10), range(r+c,10+r+c)) #Graphique approprié
plt.show()
Mais aux sous-graphiques (),
Il présente l'inconvénient de ne pas être facile à utiliser. Surtout, il est difficile à utiliser lorsque vous souhaitez visualiser facilement l'image sur jupyter.
La première idée que j'ai eue était d'appeler subplots () et de show () ligne par ligne.
subplots_1row.py
import matplotlib.pyplot as plt
ncols = 5
f, axes = plt.subplots(1, ncols, figsize=(ncols*2.0, 2.0))
for i in range(13):
axes[i % 5].plot(range(10), range(i,10+i)) #Graphique approprié
if i % 5 == 4:
plt.show()
f, axes = plt.subplots(1, ncols, figsize=(ncols*2.0, 2.0))
plt.show()
Lors de l'affichage d'un grand nombre d'images, elles s'affichent petit à petit, de sorte que la sensation d'attente est grandement réduite. Vous n'avez pas à penser à la mise en page car vous n'avez besoin que du nombre de graphiques pour une ligne et des tailles verticale et horizontale.
C'est bien si vous souhaitez l'intégrer dans une simple boucle. Cependant, le processus de vérification des axes est fastidieux.
Je ne veux pas écrire le processus gênant plusieurs fois, alors j'en ai fait un générateur.
axes_generator.py
import matplotlib.pyplot as plt
def axes_generator(ncols):
while True:
f, axes = plt.subplots(1, ncols, figsize=(ncols*2.0, 2.0))
for c in range(ncols):
yield axes[c]
plt.show()
ag = axes_generator(5)
for i, ax in zip(range(13), ag):
ax.plot(range(10), range(i,10+i)) #Graphique approprié
plt.show()
Grâce au générateur, le processus de dessin du graphe peut lui être consacré. L'intérieur de la boucle est rafraîchissant et facile à lire.
Si vous voulez ajouter un graphe, appelez __next__ ()
et l'itérateur retournera les axes suivants.
ag = axes_generator(5)
for i, ax in zip(range(13), ag):
ax.plot(range(10), range(i,10+i)) #Graphique approprié
if i % 3 == 2:
ax = ag.__next__()
ax.bar(range(5), range(i,i+5)) #Graphique approprié
plt.show()
Mais c'est gênant de voir les haches supplémentaires.
Je voulais cacher l'excès, j'ai donc décidé de le classer. --Peut être utilisé comme générateur.
AxesGenerator.py
import matplotlib.pyplot as plt
class AxesGenerator:
def __init__(self, ncols:int=6, figsize:tuple=None, *args, **kwargs):
self._ncols = ncols
self._figsize = figsize
self._axes = []
def __iter__(self):
while True:
yield self.get()
def get(self):
if len(self._axes) == 0:
plt.show()
f, axes = plt.subplots(nrows=1, ncols=self._ncols, figsize=self._figsize)
self._axes = list(axes) if self._ncols > 1 else [axes,]
ax = self._axes.pop(0)
return ax
def flush(self):
for ax in self._axes:
ax.axis('off')
plt.show()
self._axes = []
ncols = 5
ag = AxesGenerator(ncols, figsize=(ncols*2.0, 2.0))
for i, ax in zip(range(13), ag):
ax.plot(range(10), range(i,10+i)) #Graphique approprié
if i % 3 == 2:
ax = ag.get()
ax.bar(range(5), range(i,i+5)) #Graphique approprié
ag.flush()
Ça devient plutôt bon. Cependant, j'appelle flush () pour nettoyer, mais j'utilise par erreur plt.show (), j'oublie de l'écrire, ou autre chose.
Vous devriez pouvoir utiliser l'instruction with pour nettoyer. Pour avec, \ _ \ _ entrez \ _ \ _ () et \ _ \ _ exit \ _ \ _ () ont été ajoutés.
Au fait, le constructeur accepte maintenant l'argument de subplots ().
AxesGenerator.py
import matplotlib.pyplot as plt
class AxesGenerator:
def __init__(self, ncols:int=6, sharey=False, subplot_kw=None, gridspec_kw=None, **fig_kw):
self._ncols = ncols
self._sharey = sharey
self._subplot_kw = subplot_kw
self._gridspec_kw = gridspec_kw
self._fig_kw = fig_kw
self._axes = []
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.flush()
return True #La gestion des exceptions est omise
def __iter__(self):
while True:
yield self.get()
def get(self):
if len(self._axes) == 0:
plt.show()
f, axes = plt.subplots(nrows=1, ncols=self._ncols, sharey=self._sharey, subplot_kw=self._subplot_kw, gridspec_kw=self._gridspec_kw, **self._fig_kw)
self._axes = list(axes) if self._ncols > 1 else [axes,]
ax = self._axes.pop(0)
return ax
def flush(self):
for ax in self._axes:
ax.axis('off')
plt.show()
self._axes = []
ncols = 5
with AxesGenerator(ncols, figsize=(ncols*2.0, 2.0)) as ag:
for i, ax in zip(range(13), ag):
ax.plot(range(10), range(i,10+i)) #Graphique approprié
if i % 3 == 2:
ax = ag.get()
ax.bar(range(5), range(i,i+5)) #Graphique approprié
J'ai pu atteindre l'objectif de visualiser rapidement un grand nombre de graphiques et d'images. Maintenant, vous pouvez même afficher les 60 000 images des enseignants du MNIST. (Je pense que si tu le fais vraiment, ça tombera en chemin)
show_mnist_OK.py
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import keras
mnist = keras.datasets.mnist.load_data()
(X_train, t_train), (X_test, t_test) = mnist
with AxesGenerator(ncols=20, figsize=(20,1)) as ag:
for x, ax in zip(X_train, ag):
ax.imshow(x, cmap=cm.gray)
ax.axis('equal')
ax.axis('off')
J'ai l'impression que je peux rendre le code un peu plus intelligent, mais un jour.