2016-03-24 8 views
3

So in Python habe ich den folgenden Code ein, von this answer genommen:Matplotlib speichern nur Text ohne Leerzeichen

import matplotlib.pyplot as plt             
import sympy                  

x = sympy.symbols('x')        
y = 1 + sympy.sin(sympy.sqrt(x**2 + 20))           
lat = sympy.latex(y)                

#add text         
plt.text(0, 0.6, r"$%s$" % lat, fontsize = 50)         

#hide axes                  
fig = plt.gca()                 
fig.axes.get_xaxis().set_visible(False)           
fig.axes.get_yaxis().set_visible(False)           
plt.savefig('out.png', bbox_inches='tight', pad_inches=0)               
plt.show() 

Dieser den Text öffnet und exportiert sie in eine PNG-Datei einfach gut:

Image Export 1

Aber das schließt Whitespace außerhalb des Whitespace außerhalb des Rahmens ein. Wie würdest du das Bild beschneiden, um nur den Text zu exportieren, wie eine Begrenzungsbox?

enter image description here

+1

Sie können die 'Vorschau verwenden (expr, viewer = 'Datei', filename = 'output.png')' Funktion von SymPy LaTeX zu erzeugen. – asmeurer

Antwort

3

Das folgende ist keine perfekte Lösung, aber es wird Ihnen hoffentlich ein paar Ideen, wie man den Fortschritt:

import matplotlib.pyplot as plt 
import sympy 

x = sympy.symbols('x') 
y = 1 + sympy.sin(sympy.sqrt(x**2 + 2)) 
lat = sympy.latex(y) 

fig = plt.figure() 
renderer = fig.canvas.get_renderer() 
t = plt.text(0.001, 0.001, r"$%s$" % lat, fontsize = 50) 
wext = t.get_window_extent(renderer=renderer) 

fig.set_size_inches(wext.width/65, wext.height/40, forward=True) 
fig.patch.set_facecolor('white') 
plt.axis('off') 
plt.tight_layout() 
plt.savefig('out.png', bbox_inches='tight', pad_inches=0) 
plt.show() 

Die Idee ist, dass Sie die Größe Ihres Textes bestimmen können Abrufen des Fensterbereichs mit dem aktuellen Renderer. Es ist dann auch möglich, eine Figurengröße manuell festzulegen. Ich bin mir jedoch nicht sicher über den richtigen Ansatz, um zwischen den beiden zu konvertieren. Beachten Sie, Ich habe eine Grenze zu dem Bild, so dass Sie, dass die Menge des verbleibenden padding sehen:

matplotlib output


Als mögliche Abhilfe für dieses Problem wird folgender Ansatz macht einfach Gebrauch von Python PIL-Bibliothek automatisch das Bild beschneiden, bevor sie zu speichern:

import io 
from PIL import Image, ImageOps 
import matplotlib.pyplot as plt 
import sympy 

x = sympy.symbols('x') 
y = 5 /sympy.sqrt(1 + sympy.sin(sympy.sqrt(x**2 + 2))) 
lat = sympy.latex(y) 

fig = plt.figure() 
t = plt.text(0.001, 0.001, r"$%s$" % lat, fontsize = 50) 

fig.patch.set_facecolor('white') 
plt.axis('off') 
plt.tight_layout() 

with io.BytesIO() as png_buf: 
    plt.savefig(png_buf, bbox_inches='tight', pad_inches=0) 
    png_buf.seek(0) 
    image = Image.open(png_buf) 
    image.load() 
    inverted_image = ImageOps.invert(image.convert("RGB")) 
    cropped = image.crop(inverted_image.getbbox()) 
    cropped.save('out.png') 
+0

Hmm ... sieht so aus, als könnte es funktionieren, aber es scheint nicht möglich zu sein, den aktuellen Renderer unter OSX zu bekommen, sogar mit der Problemumgehung von [this] (http://stackoverflow.com/a/22689498/3807128) antwort. Irgendwelche Ideen? Danke noch einmal. – satvikb

+0

Ok, löste es, auf OSX, wenn Sie [this] (http://stackoverflow.com/a/22689498/3807128) Lösung verwenden, ersetzen Sie die Zeile 'fig.canvas.print_pdf (io.BytesIO())' mit ' fig.canvas.print_figure ("out.png") ', um den Renderer zu erhalten, unter Verwendung des gleichen Dateinamens, um ihn erneut zu speichern, um ihn zu überschreiben. – satvikb

+0

Ich verstehe nicht warum es '65' und' 40' gibt, kann das jemand erklären? – shellbye

Verwandte Themen