在GAE中使用matplotlib [英] Using matplotlib in GAE
问题描述
我创建了一个简单的应用程序,仅包含处理程序脚本 hello_world。 py
import numpy as np
import os
import sys
import cStringIO
$ b $ printContent-type:image / png\\\
$ b os.environ [MATPLOTLIBDATA] = os.getcwdu()#自己的matplotlib数据
os.environ [MPLCONFIGDIR] = os.getcwdu()#自己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())
和一个配置文件 app.yaml
application:helloworldtak
版本:1
runtime:python27
api_version:1
线程安全:无
处理程序:
- url:/.*
脚本:hello_world.py
溴化锂aries:
- name:numpy
版本:latest
- 名称:matplotlib
版本:latest
我想绘制一些内容,然后将内容作为png图像返回。这个过程对于像Apache或IIS这样的普通Web服务器来说工作正常,我做了一百万次。
问题在于:当我在开发服务器中本地运行脚本时,出现一个错误,可能是由于我的MPL 1.1.1版本GAE中的实验。但是,当我将应用程序部署到GAE时,我得到了一个完全不同的,不相关的错误。
观察外观,回溯为:
Traceback(最近一次调用最后一次):
文件/base/data/home/apps/s~helloworldtak/1.364765672279579252/hello_world.py,第16行,在< module>
import matplotlib.pyplot as plt
文件/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/pyplot.py,第23行,位于< module>
from matplotlib.figure import Figure,figaspect
文件/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/figure.py,第18行,位于< module>
导入Axes,SubplotBase,subplot_class_factory
文件/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/axes.py,第14行,位于< module>
将matplotlib.axis导入为maxis
在< module>文件中,第10行的文件/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/axis.py
导入matplotlib.font_manager作为font_manager
文件/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/font_manager.py,第1324行,位于< module>
_rebuild()
文件/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/font_manager.py,第1278行,在_rebuild
fontManager = FontManager()
文件/python27_runtime/python27_lib/versions/third_party/matplotlib-1.1.1/matplotlib/font_manager.py,第995行,在__init__
self.defaultFont ['ttf'] = self.ttffiles [0 ]
IndexError:列表索引超出范围
似乎必须做些什么MPL的字体缓存。我在文档中看到缓存和文件访问是GAE中MPL存在的问题之一,但很明显,导入是为其他人使用的。
我做错了什么?
编辑
基于在下面的答案中,我改变了我的代码:
import numpy as np
import cStringIO
import matplotlib .pyplot as plt
import webapp2
$ b $ 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)
它的工作。
我不熟悉sys模块。给出我喜欢使用webapp2的问题的答案。这是一个工作处理程序:
import webapp2
pre>
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)
或者,您可以使用文件api在blobstore中编写
sio.getvalue()
,并使用方法get_serving_url()
用于避免在base64中进行编码的图像api。My tags and title quite clearly state my problem. I want to use matplotlib to create real-time plots in Google App Engine. I've read the documentation and searched on SO and Google. I found a post, pointing to this working demo. But when I try it on my own, it doesn't work for me.
I created a simple application, consisting only of a handler-script 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())
and a a configuration file 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"
I want to plot something and then return the content as png-image. This procedure works fine for a normal web-server like Apache or IIS, I did this a million times.
The problem is rather: when I run my script locally within the development server, I get an error that is probably due to my MPL version 1.1.1, which is only "experimental" in GAE. But when I deploy my app to GAE, I get a completely different, uncorrelated error.
Looking at the looks, the traceback is:
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
It seems to have to do something with the fonts-cache of MPL. I read in the docs that caching and file-access is one of the problems with MPL in GAE, but obviously, the import works for others.
What am I doing wrong?
Edit Based on the answer below, I changed my code to be
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)
and like this, it's working.
解决方案I'm not familiar with sys module. To give an answer to the question I prefer using webapp2. This is a working 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)
Alternatively, you could write the
sio.getvalue()
in the blobstore with files api and use the methodget_serving_url()
of images api for avoid to encode in base64.这篇关于在GAE中使用matplotlib的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!