[PYTHON] (Matplotlib) Ich möchte ein Diagramm mit einer in Pixel angegebenen Größe zeichnen

Einführung

Für das von matplotlib erstellte Diagramm wird Folgendes erklärt: ** Festlegen der Größe (Breite / Höhe) des Diagrammbereichs in Pixeleinheiten **.

top.png

Ausführungsumgebung (Google Colab.)

Hinweis

Im Fall einer Jupyter-Umgebung (Google Colab. Environment) ** wird das PNG-Bild in der Ausführungsergebniszelle von plt.show (...) und ** von plt.savefig (...) angezeigt ** Die Größe des PNG-Bildes **, das als Datei ausgegeben wird, ist unterschiedlich ** </ font>.

Insbesondere wird das in der Ausführungsergebniszelle ** angezeigte ** PNG-Bild ** sein. Die umgebenden Ränder werden automatisch zugeschnitten </ font> **. Ich werde.

Wenn beispielsweise der folgende Code in der Google Colab-Umgebung automatisiert ist, beträgt das in der Ausgabezelle angezeigte Bild $ 348 \ mal 270 $ (px), während das als test.png gespeicherte Bild $ 400 \ mal 300 $ beträgt. Es wird $ (px) sein.

python


import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,20,100) #Beispieldaten zum Zeichnen
y = x ** 0.5              #Beispieldaten zum Zeichnen

fig = plt.figure(dpi=100, figsize=(4,3))
plt.plot(x,y)
plt.savefig('test.png') #Ausgabe in Datei 400 x 300 px
plt.show()              #348 x 270 px werden in der Ausgabezelle angezeigt

--figsize = (4,3) gibt die" Breite "und" Höhe "des Bildes in ** Zoll-Einheiten ** an.

  • In "dpi = 100" wird "Punkt pro Zoll (= Anzahl der Punkte pro Zoll (Anzahl der Pixel)" "angegeben.
  • Die Ausgabebildgröße beträgt ** Breite ** beträgt $ 4 , \ mathrm {inch} \ mal 100 , \ mathrm {dpi} = 400 , \ mathrm {pixel} $, ** Höhe ** beträgt $ 3 \ , \ mathrm {inch} \ times 100 , \ mathrm {dpi} = 300 , \ mathrm {pixel} $ ... Es sollte sein, wird aber in der Ausgabezelle angezeigt Das Bild wird etwas kleiner </ font> mit abgeschnittenen Rändern.

Von nun an werden wir mit plt.savefig (...) zu ** Zielbildern übergehen, die als Dateien ausgegeben werden **.

Ich möchte die Größe des (Netto-) Plotbereichs anstelle der Bildgröße ermitteln

Die Bildgröße (in Pixel) könnte aus der "Größe" und "DPI" der in Zoll angegebenen "Figur" berechnet werden, wie oben beschrieben. Dies kann aus einer Instanz von "figure" ("fig") wie folgt berechnet werden:

Bildgröße berechnen (in Pixel)


fig_w_px = int(fig.get_figwidth()  * fig.get_dpi())  
fig_h_px = int(fig.get_figheight() * fig.get_dpi())
print(f'■ Fig size  {fig_w_px} x {fig_h_px} [px]')

Zunächst wird hier anstelle der Gesamtgröße dieses Bildes die Größe des (Netto-) Plotbereichs, der von ** rotem Rahmen ** </ font> ** umgeben ist, wie folgt angegeben: Wir werden herausfinden, wie ** (in Pixel) aussieht.

top2.png

Die Größe des Plotbereichs (in Pixel) kann berechnet werden, indem der Wert vom Axes-Objekt ("ax") wie folgt abgerufen wird: Da in der Abbildung Japanisch, in der Google Colab. Umgebung usw. verwendet wird, führen Sie bitte zuerst ! Pip install japanize-matplotlib aus, um die Bibliothek zu installieren.

Berechnen Sie die Größe des Plotbereichs (in Pixel).


import numpy as np
import japanize_matplotlib 
import matplotlib.pyplot as plt

x = np.linspace(0,20,100) #Beispieldaten zum Zeichnen
y = x ** 0.5              #Beispieldaten zum Zeichnen

fig = plt.figure(dpi=100, figsize=(4,3))
ax = plt.gca()
ax.plot(x,y)
ax.set_xlabel('Eingang',fontsize=12)
ax.set_ylabel('Ausgabe',fontsize=12)
plt.savefig('foo.png')

#Abbildung (Gesamtbild) Größe
fig_w_px = int(fig.get_figwidth()  * fig.get_dpi())  
fig_h_px = int(fig.get_figheight() * fig.get_dpi())
print(f'■ Fig size   {fig_w_px} x {fig_h_px} [px]')

#Größe der Achse (Plotfläche)
ax_size_inch = ax.figure.get_size_inches()
ax_w_inch = ax_size_inch[0] * (ax.figure.subplotpars.right - ax.figure.subplotpars.left)
ax_h_inch = ax_size_inch[1] * (ax.figure.subplotpars.top - ax.figure.subplotpars.bottom)
ax_w_px = int( ax_w_inch * fig.get_dpi() )  
ax_h_px = int( ax_h_inch * fig.get_dpi() )
print(f'■ Axis size  {ax_w_px } x {ax_h_px } [px]')

Das Ausführungsergebnis ist wie folgt. Wenn Sie die Dateiausgabe foo.png mit einer Bildbearbeitungssoftware usw. öffnen und die Größe des Plotbereichs überprüfen, stimmt dies mit Sicherheit mit dem folgenden Ergebnis überein.

Ausführungsergebnis


■ Fig size   400 x 300 [px]
■ Axis size  310 x 226 [px]

Programm Beschreibung

  • Mit ax.figure.get_size_inches () die Größe des Bereichs einschließlich der Gesamtgröße des Axes-Objekts (= ** Skalen und Beschriftungen für jede Achse (Zeichen wie "Eingabe" und "Ausgabe") ** ) Wird in Zoll erhalten.

  • In "ax.figure.subplotpars.left" ist es der Wert ($ 0.0 $ bis $ 1.0 $), der die ** Position am linken Rand ** des Plotbereichs darstellt, wenn die gesamte Breite des Axes-Objekts ** $ 1.0 $ beträgt. Außerdem ist "ax.figure.subplotpars.right" ein Wert, der ** die Position des rechten Randes des Plotbereichs ** darstellt.

  • Hier ist der Unterschied zwischen den beiden "ax.figure.subplotpars.right --ax.figure.subplotpars.left" die Breite des Plotbereichs, in dem die gesamte ** Breite des Axes-Objekts ** $ 1.0 $ beträgt. Es repräsentiert das Verhältnis von **.

  • Um die Breite des Plotbereichs in ** Zoll-Einheiten ** zu erhalten, die Gesamtbreite des Achsenobjekts ax_size_inch [0] (in Zoll) und die Breite (das Verhältnis) des Plotbereichs ax.figure.subplotpars.right - Mit ax.figure.subplotpars.left multiplizieren und in ax_w_inch speichern.

  • Um Zoll-Einheiten in Pixel-Einheiten umzuwandeln, wird "ax_w_inch" mit der Auflösung "fig.get_dpi ()" multipliziert und in "ax_w_px" gespeichert.

Ich möchte ein Diagramm zeichnen, indem ich die Größe des Plotbereichs in Pixel spezifiziere

Ich konnte ** die Größe des Plotbereichs in Pixel finden **.

Im Gegensatz dazu ** geben Sie diesmal die Größe des Plotbereichs in Pixel an ** und zeichnen Sie ein Diagramm. Der folgende Code ist ein Beispiel, das ein Diagramm so zeichnet, dass die Plotfläche $ 400 \ mal 300 $ (px) beträgt.

--Referenz: Demo Fixed Size Axes @ matplotlib.org

Die Ursache ist unbekannt, aber wenn am Ende des Programms die Größe des Plotbereichs neu berechnet und ausgegeben wird, beträgt sie "Achsengröße 387 x 302 [px]". Als ich jedoch die Größe des Plotbereichs für das tatsächlich ausgegebene Bild (foo.png) gemessen habe, war es korrekt $ 400 \ mal 300 $ (px).

Diagrammausgabe durch Angabe der Größe des Plotbereichs in Pixel


import numpy as np
import japanize_matplotlib 
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import Divider, Size #hinzufügen
from mpl_toolkits.axes_grid1.mpl_axes import Axes #hinzufügen

x = np.linspace(0,20,100) #Beispieldaten zum Zeichnen
y = x ** 0.5              #Beispieldaten zum Zeichnen

ax_w_px = 400  #Geben Sie die Breite des Plotbereichs in Pixel an
ax_h_px = 300  #Geben Sie die Höhe des Plotbereichs in Pixel an

#Verarbeitung zur Größenangabe ↓ ↓ Ab hier ↓ ↓
fig_dpi = 100
ax_w_inch = ax_w_px / fig_dpi
ax_h_inch = ax_h_px / fig_dpi
ax_margin_inch = (0.5, 0.5, 0.5, 0.5)  # Left,Top,Right,Bottom [inch]

fig_w_inch = ax_w_inch + ax_margin_inch[0] + ax_margin_inch[2] 
fig_h_inch = ax_h_inch + ax_margin_inch[1] + ax_margin_inch[3]

fig = plt.figure( dpi=fig_dpi, figsize=(fig_w_inch, fig_h_inch))
ax_p_w = [Size.Fixed(ax_margin_inch[0]),Size.Fixed(ax_w_inch)]
ax_p_h = [Size.Fixed(ax_margin_inch[1]),Size.Fixed(ax_h_inch)]
divider = Divider(fig, (0.0, 0.0, 1.0, 1.0), ax_p_w, ax_p_h, aspect=False)
ax = Axes(fig, divider.get_position())
ax.set_axes_locator(divider.new_locator(nx=1,ny=1))
fig.add_axes(ax)
#Verarbeitung zur Größenangabe ↑↑ Bis hierher ↑↑

ax.plot(x,y)
ax.set_xlabel('Eingang',fontsize=12)
ax.set_ylabel('Ausgabe',fontsize=12)
plt.savefig('foo.png')

#Abbildung (Gesamtbild) Größe
fig_w_px = int(fig.get_figwidth()  * fig.get_dpi())  
fig_h_px = int(fig.get_figheight() * fig.get_dpi())
print(f'■ Fig size   {fig_w_px} x {fig_h_px} [px]')

#Größe der Achse (Plotfläche)
ax_size_inch = ax.get_figure().get_size_inches()
ax_w_inch = ax_size_inch[0] * (ax.figure.subplotpars.right - ax.figure.subplotpars.left)
ax_h_inch = ax_size_inch[1] * (ax.figure.subplotpars.top - ax.figure.subplotpars.bottom)
ax_w_px = int( ax_w_inch * fig.get_dpi() )  
ax_h_px = int( ax_h_inch * fig.get_dpi() )
print(f'■ Axis size  {ax_w_px } x {ax_h_px } [px]') 
#Die obige Druckausgabe führt nicht zu 400 x 300,
#Tatsächliches Bild ('foo.png'), Die Größe der Grundstücksfläche beträgt 400 x 300

Recommended Posts