要设置 Bokeh 应用程序,我创建一个父目录来保存名为 bokeh_app 的所有内容。 在这个目录中,我们将有一个数据子目录(称为 data),我们脚本的子目录(scripts)和一个 main.py 脚本将所有内容整合到一起。 通常,为了管理所有代码,我发现最好将每个选项卡的代码保存在单独的 Python 脚本中,并从单个主脚本中调用它们。 以下是我用于 Bokeh 应用程序的文件结构,该文件结构改编自官方文档。
bokeh_app | +--- data | +--- info.csv | +--- info2.csv | +--- scripts | +--- plot.py | +--- plot2.py | +--- main.py对于这次我们分析的航班程序项目,文件结构遵循一般大纲,如下:
在一个 bokeh_app 目录下有三个主要部分:data,scripts 和 main.py。 当运行服务器时,我们告诉 Bokeh 服务于 bokeh_app 目录,它将自动搜索并运行 main.py 脚本。 有了一般的结构,让我们来看看 main.py ,这就是我喜欢称之为 Bokeh 应用程序的执行者!
主程序文件 (main.py)main.py 脚本就像一个 Bokeh 应用程序的执行程序。 它加载数据,将其传递给其他脚本,返回结果图,并将它们组织到一个显示中。 这将是我完整展示的唯一脚本,因为它对应用程序尤其重要。
# Pandas for data management import pandas as pd # os methods for manipulating paths from os.path import dirname, join # Bokeh basics from bokeh.io import curdoc from bokeh.models.widgets import Tabs # Each tab is drawn by one script from scripts.histogram import histogram_tab from scripts.density import density_tab from scripts.table import table_tab from scripts.draw_map import map_tab from scripts.routes import route_tab # Using included state data from Bokeh for map from bokeh.sampledata.us_states import data as states # Read data into dataframes flights = pd.read_csv(join(dirname(__file__), \'data\', \'flights.csv\'), index_col=0).dropna() # Formatted Flight Delay Data for map map_data = pd.read_csv(join(dirname(__file__), \'data\', \'flights_map.csv\'), header=[0,1], index_col=0) # Create each of the tabs tab1 = histogram_tab(flights) tab2 = density_tab(flights) tab3 = table_tab(flights) tab4 = map_tab(map_data, states) tab5 = route_tb(flights) # Put all the tabs into one application tabs = Tabs(tabs = [tab1, tab2, tab3, tab4, tab5]) # Put the tabs in the current document for display curdoc().add_root(tabs)我们从必要的导入开始,包括制作选项卡的函数,每个函数都存储在 scripts 目录中的单独脚本中。 如果查看文件结构,请注意 scripts 目录中有一个 __init __.py 文件。 这是一个完全空白的文件,需要放在目录中,以便我们使用相对语句导入相应的函数(例如 from scripts.histogram import histogram_tab)。 我不太确定为什么需要它,但是它有效。
在 Python 库和脚本导入之后,我们在Python __file__ 属性的帮助下读取必要的数据。 在这种情况下,我们使用两个 pandas dataframe( flights 和 map_data)以及 Bokeh 中包含的美国各州的数据。 一旦读入数据,脚本就会进行委托:它将适当的数据传递给每个函数,每个函数都绘制并返回一个选项卡,主脚本将所有这些选项卡组织在一个名为 tabs 的布局中。 作为每个单独的选项卡函数的功能示例,让我们看一下绘制 map_tab 的函数。
此函数包含 map_data(航班数据的格式化版本)和美国各州的数据,并为选定的航空公司生成航班路线图:
def map_tab(map_data, states): ... def make_dataset(airline_list): ... return new_src def make_plot(src): ... return p def update(attr, old, new): ... new_src = make_dataset(airline_list) src.data.update(new_src.data) controls = ... tab = Panel(child = layout, title = \'Flight Map\') return tab我们看到熟悉的 make_dataset ,make_plot 和 update 函数用于绘制带有交互式控件的图。 一旦我们设置了绘图,最后一行将整个绘图返回到主脚本。 每个单独的脚本(5个选项卡中有5个)遵循相同的模式。
接下来返回主脚本,最后一步是收集选项卡并将它们添加到单个文档中。
# Put all the tabs into one application tabs = Tabs(tabs = [tab1, tab2, tab3, tab4, tab5]) # Put the tabs in the current document for display curdoc().add_root(tabs)选项卡显示在应用程序的顶部,就像任何浏览器中的选项卡一样,我们可以轻松地在它们之间切换以探索数据。