使用Tornado显示Bokeh生成的文件
我正在开发一个网站,用户可以在上面上传文件,然后后台会分析这些文件,生成一些互动图形(比如散点图和直方图),最后把这些图形返回给浏览器,供用户操作。可以想象成把Excel放到网上,用户上传文件后,可以得到图形并对其进行操作。我考虑了多种方案,最终决定使用Bokeh来绘图。我写了一个Python脚本和一个HTML页面来上传文件。通过Bokeh,我成功创建了一个输出文件(比如“plot.html”),这个过程很顺利。
另外,我安装了Tornado,这样我就可以上传并动态读取一个简单的文件(比如“test.txt”),然后把文件内容返回到output.html中。这部分也运行得很好。
但是,当我修改为Tornado使用的脚本,以便显示之前用Bokeh生成的plot.html时,这就不行了。Bokeh生成的HTML(包含图形对象)是否有什么特别之处,使得Tornado无法正确显示呢?例如,我听说数据库搜索的结果中可能包含一些无法序列化的元素,而这些非序列化的元素需要在显示搜索结果之前被移除。我在想,是否也有类似的情况发生。
以下是一些相关的脚本:
display.py: 用于通过Tornado读取和返回文件内容。这个脚本可以正常工作,返回test.txt的内容,正如预期的那样。
import os.path
import random
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
define("port", default=80, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
class OutputHandler(tornado.web.RequestHandler):
def post(self):
fname = self.get_argument('upfile')
f = open(fname, 'r')
lines = f.readlines()
self.render('plot.html', content=lines)
if __name__ == '__main__':
tornado.options.parse_command_line()
app = tornado.web.Application(
handlers=[(r'/', IndexHandler), (r'/content', OutputHandler)],
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
debug=True
)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
plot.py:用于读取和生成Bokeh图形的脚本。这个脚本也能正常工作,并创建包含生成图形的plot.html。
from bokeh.plotting import *
output_file("plot.html")
filename = 'test.dat'
f=open(filename,'r')
#####
# deleted lines for manipulating data
#####
scatter(ndarray[:1000,0], ndarray[:1000,1], color='red', alpha=0.7)
quad(top=hist, bottom=np.zeros(len(hist)), left=edges[:-1], right=edges[1:],
fill_color="#036564", line_color="#033649")
display_plot.py:用于通过Tornado显示Bokeh生成的plot.html的脚本。这个脚本却无法正常工作。
import os.path
import random
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
define("port", default=80, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('plot.html')
# the rest the same as in display.py for now.
这个最后的脚本让我觉得,显示一个包含图形对象的Bokeh生成的HTML,与显示其他仅包含文本和图形的HTML文件并不相同,后者可以正确渲染。这个说法是否正确?我该如何使用Tornado(或者其他任何网络服务)来显示plot.html呢?
谢谢你的帮助。
1 个回答
RequestHandler.render
会把一个文件当作 Tornado 模板来处理。这意味着某些字符组合(特别是双大括号 {{ }}
)有特别的含义。如果你只是想直接提供一个文件,不想让它被处理成模板,那就用 write
而不是 render
:
with open('plot.html') as f:
self.write(f.read())