抱歉,如果在StackOverflow的其他地方回答了这个问题,我会在发布此问题之前尽力搜索答案。
我正在使用Bokeh创建一个基于Flask的Web应用程序,用于工作中的数据可视化。我使用bokeh.embed.components和bokeh.plotting.figure嵌入散点图/线图没有问题。
我想显示用于在绘图下方的DataTable小部件中创建绘图的数据。不幸的是,使用组件生成脚本和div似乎不适用于小部件。使用使用bokeh.layouts创建的列,行或布局时,组件似乎也会失败。
我的代码的总体布局是一个Python文件,其中包含我的Flask应用程序,以及一个包含我的网页布局的HTML文件。 Python文件的总体布局如下:
from flask import Flask, render_template
import pandas as pd
import numpy as np
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.plotting import figure
from bokeh.layouts import widgetbox, column
from bokeh.embed import components
app = Flask(__name__)
x = np.linspace(0, 2, 1000)
y = np.sin(x)
df = pd.DataFrame({"x": x, "y":y}) # Not sure how to provide sample data
@app.route("/")
def index():
p = figure()
p.scatter(df['x'], df['y'])
data_source = ColumnDataSource(df)
columns = [
TableColumn(field="field1", title="Field 1"),
TableColumn(field="field2", title="Field 2"),
TableColumn(field="field3", title="Field 3"),
]
data_table = DataTable(source=data_source, columns=columns)
script, div = components(column(p, widgetbox(data_table)))
return render_template('sample.html', script=script, div=div)
HTML模板(“sample.html”)看起来如下所示:
<html>
<head>
<link
href="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css"
rel="stylesheet" type="text/css">
<link
href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css"
rel="stylesheet" type="text/css">
<script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js"></script>
</head>
<body>
{{ script|safe }}
{{ div|safe }}
</body>
</html>
我选择使用简单的正弦波作为此代码的示例数据,但在现实生活中,我使用Excel文件(pd.read_excel)在将Web应用程序连接到数据库之前测试代码。
在Python代码中,如果我替换
script, div = components(column(p, widgetbox(data_table))
同
script, div = components(p)
代码完美无缺。因此,这让我相信问题在于嵌入窗口小部件或绘图和窗口小部件的布局。提前感谢您提供的任何帮助。
为了它的价值,我意识到我的原始代码出了什么问题。显然,当将DataTables与组件一起使用时,需要链接到CSS和JS for bokeh-tables。以下是相关的链接和脚本标记。
<link
href="http://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.css"
rel="stylesheet" type="text/css">
<script src="http://cdn.pydata.org/bokeh/release/bokeh-tables-1.0.4.min.js"></script>
下面的代码为Bokeh v1.0.4正确渲染了图和表
import numpy as np
import pandas as pd
import webbrowser
from flask import Flask, render_template
from tornado.ioloop import IOLoop
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.embed import server_document
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.server.server import Server
from bokeh.layouts import column
app = Flask(__name__)
port = 5001
def get_plot(doc):
x = np.linspace(0, 2, 1000)
y = np.sin(x)
df = pd.DataFrame({"x": x, "y":y}) # Not sure how to provide sample data
def get_plot():
p = figure()
p.scatter(df['x'], df['y'])
data_source = ColumnDataSource(df)
columns = [ TableColumn(field = "field1", title = "Field 1"),
TableColumn(field = "field2", title = "Field 2"),
TableColumn(field = "field3", title = "Field 3"), ]
data_table = DataTable(source = data_source, columns = columns)
return column(p, data_table)
doc.add_root(get_plot())
doc.title = "Flask App Plot"
bokeh_app = Application(FunctionHandler(get_plot))
@app.route('/', methods = ['GET'])
def index():
script = server_document('http://localhost:5006/bkapp')
return render_template("index.html", script = script)
def bk_worker():
server = Server({'/bkapp': bokeh_app}, io_loop = IOLoop(), allow_websocket_origin = ["localhost:{}".format(port)], port = port)
server.start()
server.io_loop.start()
from threading import Thread
Thread(target = bk_worker).start()
if __name__ == '__main__':
print('Opening single process Flask app with embedded Bokeh application on http://localhost:{}/'.format(port))
webbrowser.open_new("http://localhost:{}/".format(port))
app.run(port = port, debug = False)
结果: