(数据科学学习手札121)Python+Dash快速web应用开发——项目结构篇 (2)

  同样地,也推荐将监听url变化从而渲染不同页面的路由回调一并写在app.py中,方便后续的管理与升级:

# 路由总控 @app.callback( Output('page-content', 'children'), Input('url', 'pathname') ) def render_page_content(pathname): if pathname == 'http://www.likecs.com/': return index_page elif pathname == 'http://www.likecs.com/age': return age_page elif pathname == 'http://www.likecs.com/sex': return sex_page elif pathname == 'http://www.likecs.com/statistics': return statistics_page return html.H1('您访问的页面不存在!') 2.2.4 在views子模块中构建多页面前端内容

  在上一小节的路由回调中你可能会好奇不同url下的返回值index_page、age_page等都是什么,这些都构建在子模块views下:

+ views/ • age.py • index.py • sex.py • statistics.py • __init__.py

  譬如其中之一的age.py内容如下:

import dash_html_components as html import dash_core_components as dcc import dash_bootstrap_components as dbc import pandas as pd import plotly.express as px from models.age import Age age_data = ( pd.DataFrame(Age.fetch_all()).rename(columns={ 'region': '地区', 'prop_0_to_14': '0到14岁人口占比', 'prop_15_59': '15到59岁人口占比', 'prop_60_above': '60岁以上人口占比', 'prop_65_above': '65岁以上人口占比' }) ) fig = px.bar(age_data.melt(id_vars=['地区'], value_vars=['0到14岁人口占比', '15到59岁人口占比', '60岁以上人口占比'], var_name='年龄段', value_name='占比(%)'), y="地区", x="占比(%)", color="年龄段", title="七普各地区人口年龄结构", color_discrete_map={ '0到14岁人口占比': '#0868ac', '15到59岁人口占比': '#43a2ca', '60岁以上人口占比': '#a8ddb5' }, orientation='h') fig.update_layout( font=dict( family="Times New Roman, SimSun" ) ) fig.update_layout(xaxis_range=[0, 100]) fig.update_layout( margin=dict(t=50, b=10) ) age_page = html.Div( [ html.Div( dbc.Table.from_dataframe(age_data, striped=True), style={ 'overflowY': 'auto', 'flex': '1' } ), html.Div( dcc.Graph(figure=fig, style={'height': '100%'}), style={ 'flex': '1', 'height': '100%' } ) ], style={ 'display': 'flex', 'height': '100%' } )

  通过这种方式针对不同页面构建相应的前端对象,从而在app.py中按照下列方式导入就可以使用了:

from views.index import index_page from views.age import age_page from views.sex import sex_page from views.statistics import statistics_page 2.2.5 在callbacks子模块中构建多页面后端逻辑

  当你在views下构建的页面内容中涉及到回调交互的功能时,我推荐将对应的后端回调逻辑拆分到callbacks子模块下同名文件中,这样非常便于编写与维护。

  同时一定要记住在views下对应的前端子模块中,一定要导入callbacks中对应的回调子模块内部的至少一个对象,否则Dash在打包应用时是扫描不到相应的回调函数内容进行编译的,进而会导致应用启动时回调无效,譬如在views/statistics.py中我们就执行了from callbacks.statistics import statistics_data。

2.2.6 在models子模块下定义数据模型

  前面说的很多内容都关乎Dash应用的构建,而当你的Dash应用依赖外部数据时,推荐的方式是类似flask项目那样构建子模块models来定义数据模型,实现与数据库的关联。

  而我们今天的可视化看板案例中就配合整合数据库篇介绍的peewee相关知识,分别定义了数据模型对应了七普中的年龄结构、性别结构以及六普七普对比数据表,并在views、callbacks等涉及的子模块中导入并调用,以年龄结构models/age.py为例:

from peewee import SqliteDatabase, Model from peewee import CharField, FloatField db = SqliteDatabase('models/age.db') class Age(Model): # 地区,唯一 region = CharField(unique=True) # 0-14岁占比 prop_0_to_14 = FloatField() # 15-59岁占比 prop_15_59 = FloatField() # 60岁及以上占比 prop_60_above = FloatField() # 65岁及以上占比 prop_65_above = FloatField() class Meta: database = db primary_key = False # 禁止自动生成唯一id列 @classmethod def fetch_all(cls): return list(cls.select().dicts())

  而本文案例中涉及到的数据可视化内容均由plotly及plotly.express实现,关于这部分内容我会在之后的进阶教程中加以概括。

  本文完整项目案例源码+附件你可以在文章开头链接页面查看和下载。

  下期我将带大家学习如何在Linux、Windows等系统中正式部署Dash应用,敬请期待。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwwxff.html