我的标签和标题清楚地说明了我的问题。我想使用matplotlib在Google App Engine中创建实时图。我已阅读documentation并在SO和Google上搜索过。我发现了一个帖子,指向this working demo。但是当我自己尝试时,它对我不起作用。
我创建了一个简单的应用程序,仅包含一个处理程序脚本 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())
和配置文件 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"
我想绘制一些内容,然后将内容作为png-image返回。这个程序适用于像Apache或IIS这样的普通Web服务器,我这样做了一百万次。
问题是:当我在开发服务器中本地运行我的脚本时,我得到的错误可能是由于我的MPL版本1.1.1,这只是GAE中的“实验性”。但是,当我将我的应用程序部署到GAE时,我得到一个完全不同的,不相关的错误。
看看外观,追溯是:
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
似乎必须对MPL的fonts-cache做一些事情。我在文档中读到缓存和文件访问是GAE中MPL的问题之一,但显然,导入适用于其他人。
我做错了什么?
修改 根据下面的答案,我将我的代码更改为
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)
并且像这样,它正在发挥作用。
答案 0 :(得分:7)
我不熟悉sys模块。为了回答我更喜欢使用webapp2的问题。这是一个有效的处理程序:
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)
或者,您可以使用文件api在blobstore中编写sio.getvalue()
并使用图像api的get_serving_url()
方法,以避免在base64中进行编码。
答案 1 :(得分:2)
问题是您在导入matplotlib之前将MATPLOTLIBDATA
和MPLCONFIGDIR
环境变量设置到您的app目录。由于您的app目录中没有任何字体,因此无法加载任何字体。