Wenn Sie mit jupyter Bilder erkennen, möchten Sie möglicherweise viele Bilder und Grafiken anordnen. Alle MNIST-Lehrerbilder anzeigen. (Wenn du es wirklich tust, wirst du nicht zurückkommen und ich denke, es wird fallen)
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()
Es wurde jedoch ärgerlich, jedes Mal matplotlib aufzurufen, wenn ich eine Grafik oder ein Bild zeichnete. Daher habe ich einen Mechanismus erstellt, um es ohne Erlaubnis anzuzeigen.
matplotlib.pyplot.subplots()
Verwenden Sie subplots (), um Bilder und Grafiken anzuordnen.
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)) #Entsprechende Grafik
plt.show()
Aber zu Nebenhandlungen (),
Es hat den Nachteil, dass es nicht einfach zu bedienen ist. Insbesondere ist es schwierig zu verwenden, wenn Sie das Bild einfach auf jupyter anzeigen möchten.
Die erste Idee, die ich hatte, war, subplots () und show () Zeile für Zeile aufzurufen.
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)) #Entsprechende Grafik
if i % 5 == 4:
plt.show()
f, axes = plt.subplots(1, ncols, figsize=(ncols*2.0, 2.0))
plt.show()
Wenn eine große Anzahl von Bildern angezeigt wird, werden sie nach und nach angezeigt, sodass das Gefühl des Wartens erheblich reduziert wird. Sie müssen nicht über das Layout nachdenken, da Sie nur die Anzahl der Diagramme für eine Linie sowie die vertikalen und horizontalen Größen benötigen.
Dies ist in Ordnung, wenn Sie es in eine einfache Schleife integrieren möchten. Das Überprüfen der Achsen ist jedoch umständlich.
Ich möchte den mühsamen Prozess nicht oft schreiben, also habe ich ihn zu einem Generator gemacht.
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)) #Entsprechende Grafik
plt.show()
Dank des Generators kann der Prozess des Zeichnens des Diagramms diesem gewidmet werden. Das Innere der Schleife ist erfrischend und leicht zu lesen.
Wenn Sie ein Diagramm hinzufügen möchten, rufen Sie __next__ ()
auf, und der Iterator gibt die folgenden Achsen zurück.
ag = axes_generator(5)
for i, ax in zip(range(13), ag):
ax.plot(range(10), range(i,10+i)) #Entsprechende Grafik
if i % 3 == 2:
ax = ag.__next__()
ax.bar(range(5), range(i,i+5)) #Entsprechende Grafik
plt.show()
Aber es ist unangenehm, die zusätzlichen Achsen zu sehen.
Ich wollte den Überschuss verbergen, also beschloss ich, ihn zu klassifizieren.
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)) #Entsprechende Grafik
if i % 3 == 2:
ax = ag.get()
ax.bar(range(5), range(i,i+5)) #Entsprechende Grafik
ag.flush()
Es wird ziemlich gut. Ich rufe jedoch flush () auf, um aufzuräumen, aber ich verwende fälschlicherweise plt.show (), vergesse, es zu schreiben, oder etwas anderes.
Sie sollten in der Lage sein, die with-Anweisung zum Bereinigen zu verwenden. Für mit wurden \ _ \ _ enter \ _ \ _ () und \ _ \ _ exit \ _ \ _ () hinzugefügt.
Übrigens akzeptiert der Konstruktor jetzt das Argument von 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 #Ausnahmebehandlung entfällt
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)) #Entsprechende Grafik
if i % 3 == 2:
ax = ag.get()
ax.bar(range(5), range(i,i+5)) #Entsprechende Grafik
Ich konnte das Ziel erreichen, schnell eine große Anzahl von Grafiken und Bildern anzuzeigen. Jetzt können Sie sogar alle 60.000 MNIST-Lehrerbilder anzeigen. (Ich denke, wenn du es wirklich tust, wird es auf den Weg fallen)
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')
Ich habe das Gefühl, dass ich den Code ein bisschen schlauer machen kann, aber eines Tages.