2013-01-22 10 views
11

Meine Tags und Titel ziemlich deutlich mein Problem. Ich möchte mit matplotlib Echtzeit-Plots in Google App Engine erstellen. Ich habe die documentation gelesen und auf SO und Google gesucht. Ich habe einen Post gefunden, der auf this working demo zeigt. Aber wenn ich es selbst versuche, funktioniert es nicht für mich.Verwendung von Matplotlib in GAE

habe ich eine einfache Anwendung, die nur aus einem Handler-Skript hello_world.py

import numpy as np 
import os 
import sys 
import cStringIO 

print "Content-type: image/png\n" 

os.environ["MATPLOTLIBDATA"] = os.getcwdu() # own matplotlib data 
os.environ["MPLCONFIGDIR"] = os.getcwdu() # own matplotlibrc 
import matplotlib.pyplot as plt 

plt.plot(np.random.random((20))) #imshow(np.random.randint((10,10))) 

sio = cStringIO.StringIO() 
plt.savefig(sio, format="png") 
sys.stdout.write(sio.getvalue()) 

und aa Konfigurationsdatei app.yaml

application: helloworldtak 
version: 1 
runtime: python27 
api_version: 1 
threadsafe: no 

handlers: 
- url: /.* 
    script: hello_world.py 

libraries: 
- name: numpy 
    version: "latest" 
- name: matplotlib 
    version: "latest" 

ich etwas darstellen möchten und dann den Inhalt als PNG-Bild zurückgeben. Dieses Verfahren funktioniert gut für einen normalen Webserver wie Apache oder IIS, ich habe das millionenfach gemacht.

Das Problem ist eher: wenn ich mein Skript lokal auf dem Entwicklungsserver ausführen, erhalte ich einen Fehler, der wahrscheinlich auf meine MPL-Version 1.1.1 zurückzuführen ist, die in GAE nur "experimentell" ist. Aber wenn ich meine App für GAE bereitstelle, bekomme ich einen völlig anderen, unkorrelierten Fehler.

an den Blicken der Suche, die Zurückverfolgungs sind:

Traceback (most recent call last): 
    File "/base/data/home/apps/s~helloworldtak/1.364765672279579252/hello_world.py", line 16, in <module> 
    import matplotlib.pyplot as plt 
    File "/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/pyplot.py", line 23, in <module> 
    from matplotlib.figure import Figure, figaspect 
    File "/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/figure.py", line 18, in <module> 
    from axes import Axes, SubplotBase, subplot_class_factory 
    File "/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/axes.py", line 14, in <module> 
    import matplotlib.axis as maxis 
    File "/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/axis.py", line 10, in <module> 
    import matplotlib.font_manager as font_manager 
    File "/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/font_manager.py", line 1324, in <module> 
    _rebuild() 
    File "/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/font_manager.py", line 1278, in _rebuild 
    fontManager = FontManager() 
    File "/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/font_manager.py", line 995, in __init__ 
    self.defaultFont['ttf'] = self.ttffiles[0] 
IndexError: list index out of range 

Es scheint etwas mit dem Schriftart-Cache von MPL zu tun zu haben. Ich habe in den Dokumenten gelesen, dass Caching und Dateizugriff eines der Probleme mit MPL in GAE sind, aber offensichtlich funktioniert der Import für andere.

Was mache ich falsch?

bearbeiten Basierend auf der Antwort unten, änderte ich meinen Code

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

import webapp2 

class MainPage(webapp2.RequestHandler): 
    def get(self): 
     plt.plot(np.random.random((20)),"r-") 
     sio = cStringIO.StringIO() 
     plt.savefig(sio, format="png") 
     self.response.headers['Content-Type'] = 'image/png' 

     self.response.out.write(sio.getvalue()) 

app = webapp2.WSGIApplication([('/', MainPage)], 
           debug=True) 

und so zu sein, es funktioniert.

+0

Um klar zu sein, scheitert es unter localhost? und woher hast du deine app.yaml-datei erhalten? (Python 7 ruft normalerweise das Hauptskript als hello_world.app auf) –

+0

Ich habe es gemäß dem "Erste Schritte" Handbuch erstellt. Ich habe es dann gemäß Handbuch in eine 2.7-Version migriert. –

+0

Es fehlschlägt unter localhost und wenn für GAE bereitgestellt. Aber: Ausnahme und Rückverfolgung unterscheiden sich. Ich habe die lokale nicht eingeschlossen, da ich lokale Inkompatibilitäten als möglichen Ursprung des Problems ausschließen wollte. –

Antwort

7

Ich bin nicht vertraut mit Sys-Modul. Um eine Antwort auf die Frage zu geben, bevorzuge ich webapp2. Dies ist ein Arbeits Handler:

import webapp2 
import StringIO 
import numpy as np 
import matplotlib.pyplot as plt 


class MainPage(webapp2.RequestHandler): 
    def get(self): 
     plt.plot(np.random.random((20))) 
     sio = StringIO.StringIO() 
     plt.savefig(sio, format="png") 
     img_b64 = sio.getvalue().encode("base64").strip() 
     plt.clf() 
     sio.close() 
     self.response.write("""<html><body>""") 
     self.response.write("<img src='data:image/png;base64,%s'/>" % img_b64) 
     self.response.write("""</body> </html>""") 

app = webapp2.WSGIApplication([('/', MainPage)], debug=True) 

Alternativ können Sie die sio.getvalue() im Blobstore mit Dateien api schreiben und die Methode get_serving_url() der Bilder api für vermeiden in base64 zu kodieren verwenden.

+0

Vielen Dank für Ihr Feedback. Mein Problem ist, dass ich Matplotlib nicht einmal importieren kann. Vielleicht ist meine App-Konfiguration das Problem? wie sieht dein aus? –

+0

Ihre app.yaml sieht gut aus, mit Ausnahme von zwei Dingen: hallo_world.APP als @peterretief kommentiert und der webapp2-Import in 'Bibliotheken'. Dieses Skript funktioniert nur in der Produktion. –

+0

Ich habe es geschafft, basierend auf Ihrem Beispiel zu arbeiten, obwohl ich wirklich nicht HTML, sondern PNG-Dateien erstellen möchte. Ich werde meinen Code an meine Frage anhängen. –

2

Das Problem bestand darin, dass Sie die Umgebungsvariablen-und MPLCONFIGDIR in Ihrem App-Verzeichnis vor dem Importieren von Matplotlib festgelegt haben. Da Sie in Ihrem Anwendungsverzeichnis keine Zeichensätze hatten, konnten keine Zeichensätze geladen werden.