Dash 是一个用于创建数据分析型 web 应用的 Python 框架。它由 Plotly 团队开发,并且可以用来构建交互式的 web 应用程序,这些应用能够包含图表、表格、地图等多种数据可视化组件。
Dash 的特点:
- 易于使用:Dash 使用 Python 语法,对于熟悉 Python 的用户来说很容易上手。
- 交互性:Dash 支持用户交互,例如点击事件、下拉列表选择等。
- 服务器端渲染:Dash 应用程序在服务器端渲染,然后将结果发送到客户端浏览器。
- 响应式设计:Dash 提供了对移动设备友好的布局。
- 与 Plotly.js 集成:Dash 可以直接生成 Plotly.js 图表,这些图表支持缩放、平移和导出为图片等功能。
安装 Dash:
要安装 Dash,你可以使用 pip:
pip install dash
创建一个简单的 Dash 应用:
下面是一个简单的 Dash 应用示例,它展示了一个文本框和一个按钮,当点击按钮时,会在页面上显示输入的文本内容。
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Input(id='input-box', type='text', value=''),
html.Button('Submit', id='button'),
html.Div(id='output-container-button',
children='Enter a value and press submit')
])
@app.callback(
Output('output-container-button', 'children'),
[Input('button', 'n_clicks')],
[dash.dependencies.State('input-box', 'value')])
def update_output(n_clicks, value):
return f'Input: "{value}" was submitted {n_clicks} times'
if __name__ == '__main__':
app.run_server(debug=True)
这段代码定义了一个简单的 Dash 应用,它包含一个输入框 (dcc.Input
) 和一个按钮 (html.Button
)。当按钮被点击时,update_output
函数会被调用,该函数会更新页面上的文本内容。
更多资源:
- 官方文档:可以从 Plotly 的官方网站找到详细的文档和教程。
- 社区支持:Dash 有一个活跃的社区,你可以在 Stack Overflow 或者 GitHub 上提问和解决问题。
- Flask 是一个用 Python 编写的轻量级 Web 应用框架。它被设计为简单易用,适合于小型到中型项目,并且易于扩展以适应更复杂的应用需求。Flask 采用 WSGI 工具箱(如 Werkzeug)和 Jinja2 模板引擎作为其核心组件。
特点:
- 轻量级:Flask 不包含数据库抽象层、表单验证等企业级功能。这些可以通过第三方扩展来添加。
- 灵活性:Flask 允许开发者选择自己喜欢的工具和库来完成特定任务,比如数据库、表单处理等。
- 易于上手:Flask 的文档清晰且详尽,非常适合初学者。
- 扩展性:通过 Flask 扩展生态系统,可以轻松地为 Flask 应用添加额外的功能。
- 社区支持:Flask 拥有一个活跃的社区,有许多第三方插件和教程可供使用。
Flask 和 Dash是两个不同的 Web 开发框架
Flask 和 Dash(尤其是 Dash 与 Flask 的结合使用)是两个不同的 Web 开发框架,它们各有特点和用途。下面我将为您解释这两个框架的区别以及它们之间的联系。
Flask
Flask 是一个用 Python 编写的轻量级 Web 应用框架。它非常灵活,适合快速开发小型到中型的 Web 应用程序。Flask 提供了基本的功能,如路由、请求处理、会话管理等,并且可以通过扩展来添加更多功能。Flask 的核心特性包括:
- 灵活性:Flask 没有固定的数据库或界面组件,可以自由选择所需的工具和库。
- 易于上手:Flask 的文档清晰,社区活跃,适合初学者学习。
- 扩展性:通过安装扩展插件,Flask 可以很容易地扩展其功能。
Dash
Dash 是一个基于 Flask 的高级框架,专门用于创建交互式的 Web 应用程序,特别是数据可视化应用。Dash 是由 Plotly 团队开发的,它使用 React.js 作为前端库,因此可以轻松地创建复杂的用户界面。Dash 的主要特点包括:
- 声明式编程模型:Dash 允许您通过简单的 Python 函数定义应用程序的行为,而不需要深入理解前端技术。
- 内置的组件库:Dash 提供了一组丰富的 UI 组件,可以用来构建用户界面。
- 实时更新:Dash 支持实时更新数据和图表,非常适合仪表板和数据分析应用。
区别
- 用途:Flask 更通用,可以用于各种类型的 Web 应用程序;而 Dash 主要针对数据驱动的应用,特别是在数据可视化方面。
- 复杂度:Flask 需要更多的手动编码和配置,而 Dash 通过封装简化了很多工作。
- 用户界面:Flask 通常需要开发者编写 HTML、CSS 和 JavaScript 来构建用户界面,而 Dash 则提供了预构建的组件和样式。
联系
尽管 Dash 是一个独立的框架,但它实际上是建立在 Flask 之上的。这意味着:
- 基础架构:Dash 应用程序通常运行在一个 Flask 服务器上,可以利用 Flask 的路由和其他功能。
- 集成能力:你可以将 Dash 集成到现有的 Flask 应用程序中,实现更复杂的功能组合。
- 扩展性:你可以在 Dash 应用中使用 Flask 扩展来增加额外的功能。
总结来说,如果你正在寻找一个灵活且可扩展的基础框架来构建 Web 应用,那么 Flask 是一个好的选择。而如果你专注于快速开发数据可视化和分析应用,Dash 会是一个更加高效的选择。同时,你也可以将两者结合起来使用,以充分利用它们各自的优势。
Flask 的核心概念:
- 路由:URL 路由决定了哪个视图函数将被用来处理客户端请求。
- 视图函数:视图函数是处理客户端请求并返回响应的函数。
- 模板:Jinja2 是 Flask 默认使用的模板引擎,用于生成 HTML 页面。
- 请求和响应对象:Flask 提供了对请求和响应对象的支持,允许开发者访问 HTTP 请求的细节和创建响应。
创建一个简单的 Flask 应用:
下面是一个简单的 Flask 应用示例,它定义了一个路由和一个视图函数来响应 HTTP 请求。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run()
在这个例子中,我们创建了一个 Flask 应用实例,并定义了一个路由 /
,该路由关联了一个名为 hello_world
的视图函数。这个视图函数返回 "Hello, World!" 字符串作为 HTTP 响应。
Flask 的用途:
- Web 开发:构建动态网站和 Web 应用程序。
- API 开发:创建 RESTful API 服务。
- 微服务:构建可独立部署的小型服务。
- 教育:教授 Web 开发基础知识。
Flask 通常与 SQLAlchemy(ORM)、Flask-SQLAlchemy(SQLAlchemy 的 Flask 扩展)、Flask-WTF(表单处理)、Flask-Login(用户认证)等扩展一起使用,以增强其功能。
当然,让我们进一步详细探讨 Flask 和 Dash 之间的区别以及如何将它们结合使用。
Flask
特点:
- 轻量级:Flask 不包含任何特定的数据库抽象层、表单验证工具或任何其他组件。它提供了一个简洁的核心,可以轻松地与其他扩展库集成。
- 灵活性:Flask 允许开发者根据自己的需求选择合适的工具和库。例如,你可以选择 SQLAlchemy 或者其他 ORM 工具来进行数据库操作,或者使用 WTForms 进行表单验证。
- 扩展性:Flask 有一个广泛的生态系统,提供了一系列的扩展来增强其功能,例如 Flask-SQLAlchemy、Flask-WTF、Flask-Login 等。
- 简单易用:Flask 的设计使得开发者可以快速搭建 Web 应用,并且容易上手。
- 路由和视图函数:Flask 使用装饰器来定义 URL 规则和对应的视图函数,这使得路由设置变得直观且易于维护。
示例代码:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return "Hello, World!"
@app.route('/hello/<name>')
def hello(name):
return f"Hello, {name}!"
if __name__ == '__main__':
app.run(debug=True)
Dash
特点:
- 数据可视化:Dash 专为数据科学家和分析师设计,它提供了丰富的交互式图表和图形库。
- 声明式编程:Dash 允许你通过 Python 函数来描述 UI 的行为,而不是直接编写复杂的前端代码。
- React 基础:Dash 的前端是基于 React 构建的,这意味着它可以高效地处理用户输入并实时更新 UI。
- 组件库:Dash 提供了一整套预构建的组件,这些组件可以直接用于构建 UI,比如按钮、下拉列表、滑块等。
- 状态管理:Dash 内置了状态管理机制,可以方便地管理应用程序的状态。
示例代码:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Input(id='input-box', type='text', value=''),
html.Button('Submit', id='button'),
html.Div(id='output-container-button',
children='Enter a value and press submit')
])
@app.callback(
Output('output-container-button', 'children'),
[Input('button', 'n_clicks')],
[dash.dependencies.State('input-box', 'value')]
)
def update_output(n_clicks, value):
if n_clicks is None:
return 'Enter a value and press submit'
return f'Input: "{value}"'
if __name__ == '__main__':
app.run_server(debug=True)
Dash 与 Flask 的结合
尽管 Dash 是基于 Flask 构建的,但你仍然可以使用 Flask 的功能来增强你的 Dash 应用。例如,你可以使用 Flask 的路由系统来处理非 Dash 相关的请求,或者使用 Flask 的扩展来实现身份验证、数据库连接等功能。
结合示例:
假设我们有一个 Dash 应用,我们想添加一个登录页面,只允许已认证的用户访问 Dash 应用。
from flask import Flask, session, redirect, url_for
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from flask_login import LoginManager, UserMixin, login_required, login_user, logout_user
# Flask App
flask_app = Flask(__name__)
flask_app.config['SECRET_KEY'] = 'your_secret_key_here'
login_manager = LoginManager()
login_manager.init_app(flask_app)
class User(UserMixin):
def __init__(self, id):
self.id = id
@login_manager.user_loader
def load_user(user_id):
return User(user_id)
@flask_app.route('/login', methods=['GET', 'POST'])
def login():
# 登录逻辑
user = User('123456')
login_user(user)
return redirect(url_for('index'))
@flask_app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
@flask_app.route('/')
@login_required
def index():
return redirect(url_for('dash_app.index'))
# Dash App
dash_app = dash.Dash(__name__, server=flask_app, url_base_pathname='/dashboard/')
dash_app.layout = html.Div([
html.H1("Dashboard"),
dcc.Graph(id='example-graph', figure={
'data': [
{'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
{'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montreal'},
],
'layout': {
'title': 'Dash Data Visualization'
}
})
])
# 为 Dash 应用添加 Flask 的 @login_required 装饰器
@dash_app.server.route('/dashboard/')
@login_required
def dash_index():
return dash_app.index()
if __name__ == '__main__':
flask_app.run(debug=True)
在这个例子中,我们使用 Flask 来处理登录和登出操作,并且只有经过身份验证的用户才能访问 Dash 应用。这种结合方式使得你可以利用 Flask 的强大功能来增强你的 Dash 应用,同时也保持了 Dash 在数据可视化方面的优势。
1. 设置静态文件
在 Flask 中,静态文件(如 CSS、JavaScript 和图像文件)通常存储在一个名为 static
的目录中。Flask 会自动为这个目录提供服务,因此您可以在 HTML 模板中引用这些文件。
示例:
假设您的项目结构如下所示:
/my_project
/app
__init__.py
/static
style.css
/templates
index.html
run.py
在 index.html
中,您可以这样引用 style.css
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flask App</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>Hello, Flask!</h1>
</body>
</html>
这里 url_for
函数用于生成静态文件的 URL。
2. 处理表单提交
Flask 可以轻松地处理 HTML 表单提交。这通常涉及到接收 POST 请求并验证用户输入。
示例:
假设您有一个简单的登录表单:
<!-- templates/login.html -->
<form method="POST">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
<button type="submit">Login</button>
</form>
然后,在 Flask 视图函数中处理表单提交:
vb
`from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if valid_login(username, password):
return "Logged in successfully!"
else:
error = "Invalid username or password."
return render_template('login.html', error=error)
return render_template('login.html')`
3. 连接和操作数据库
Flask 可以与多种数据库系统集成,其中最常用的数据库 ORM 是 SQLAlchemy。Flask-SQLAlchemy 是一个流行的扩展,简化了 Flask 应用与 SQLAlchemy 的集成。
示例:
安装 Flask-SQLAlchemy:
pip install Flask-SQLAlchemy
配置数据库连接:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return '<User %r>' % self.username
在视图函数中查询数据库:
@app.route('/users')
def show_users():
users = User.query.all()
return render_template('users.html', users=users)
4. 用户认证和会话管理
Flask-Login 是一个常用的扩展,用于处理用户认证和会话管理。
示例:
安装 Flask-Login:
pip install Flask-Login
配置用户模型:
from flask_login import UserMixin
class User(UserMixin, db.Model):
# ... (previous code)
pass
配置 Flask-Login:
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
保护路由:
@app.route('/protected')
@login_required
def protected():
return f'Logged in as: {current_user.username}'
5. 部署 Flask 应用到生产环境
在生产环境中运行 Flask 应用通常需要使用 WSGI 服务器,例如 Gunicorn 或 uWSGI,并配合反向代理服务器如 Nginx。
示例配置:
安装 Gunicorn:
pip install gunicorn
启动应用:
gunicorn app:app
配置 Nginx:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
6. 错误处理
在 Flask 中,可以通过定义错误处理程序来捕获并响应特定类型的 HTTP 错误。这有助于提供一致的用户体验,并且可以记录错误以便于调试。
示例:
from flask import Flask, jsonify
app = Flask(__name__)
@app.errorhandler(404)
def not_found(error):
return jsonify({"error": "Not Found", "message": str(error)}), 404
@app.errorhandler(500)
def internal_server_error(error):
return jsonify({"error": "Internal Server Error", "message": str(error)}), 500
7. 单元测试
Flask 提供了一个内置的测试客户端,可以帮助您编写和运行单元测试。
示例:
import unittest
from flask import Flask, json
app = Flask(__name__)
@app.route('/api/v1/users')
def get_users():
users = [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]
return json.jsonify(users)
class TestApp(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
def test_get_users(self):
response = self.app.get('/api/v1/users')
data = json.loads(response.data)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(data), 2)
self.assertEqual(data[0]['name'], 'Alice')
if __name__ == '__main__':
unittest.main()
8. 蓝图(Blueprints)
蓝图允许您组织视图函数和其他应用程序代码到模块化结构中。这对于大型应用程序非常有用,可以避免把所有的路由和视图都放在同一个文件中。
示例:
创建一个蓝图:
from flask import Blueprint, render_template
users_bp = Blueprint('users', __name__, template_folder='templates')
@users_bp.route('/')
def index():
return render_template('users/index.html')
app.register_blueprint(users_bp, url_prefix='/users')
9. 使用环境变量
为了更好地管理和分离配置,可以使用环境变量来设置不同的配置值。例如,您可以使用环境变量来指定数据库 URI 或者密钥。
示例:
在 .env
文件中设置环境变量:
FLASK_APP=app.py
FLASK_ENV=development
SECRET_KEY=secretkey
SQLALCHEMY_DATABASE_URI=sqlite:///dev.db
然后在 Python 代码中读取这些变量:
from os import environ
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SECRET_KEY'] = environ.get('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = environ.get('SQLALCHEMY_DATABASE_URI')
db = SQLAlchemy(app)
10. 配置日志
日志对于跟踪错误和监控应用程序的性能至关重要。Flask 支持使用标准的 Python 日志模块。
示例:
配置日志:
import logging
from flask import Flask
app = Flask(__name__)
app.logger.setLevel(logging.DEBUG)
@app.route('/')
def hello_world():
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
return 'Hello, World!'
11. 部署到云平台
除了传统的部署方式,您还可以选择将 Flask 应用部署到云平台上,比如 Heroku、AWS、Google Cloud Platform 等。
示例:
部署到 Heroku:
-
创建一个
Procfile
文件:web: gunicorn app:app
-
使用 Git 将应用推送到 Heroku:
git init
git add .
git commit -m "Initial commit"
heroku create
git push heroku master
12. 使用 Docker 容器
Docker 容器提供了一种简单的方式来打包和部署应用程序及其依赖项。
示例 Dockerfile:
FROM python:3.8-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "-w", "3", "-b", "0.0.0.0:5000", "app:app"]
构建和运行 Docker 容器:
docker build -t my-flask-app .
docker run -p 5000:5000 my-flask-app
dash高级组件
- Dash Core Components (dcc):这是 Dash 提供的一组预定义的 React 组件,它们可以直接在 Python 中使用。
- Dash HTML Components (html):这是一组基本的 HTML 标签封装,可以用来构建网页布局。
- Dash Layouts:如何组织和布局你的应用。
- Dash Callbacks:如何连接前端组件与后端逻辑。
- Stateful Callbacks:如何处理状态管理。
- Dash Deployment:如何部署你的 Dash 应用。
1. Dash Core Components (dcc)
dcc
包含了许多交互组件,如滑块 (Slider
)、下拉列表 (Dropdown
)、日期选择器 (DatePickerSingle
, DatePickerRange
) 等。
示例:使用 dcc.Graph
显示动态图表
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id='graph-with-slider'),
dcc.Slider(
id='year-slider',
min=df['year'].min(),
max=df['year'].max(),
value=df['year'].min(),
marks={str(year): str(year) for year in df['year'].unique()},
step=None
),
])
@app.callback(
Output('graph-with-slider', 'figure'),
[Input('year-slider', 'value')]
)
def update_figure(selected_year):
filtered_df = df[df.year == selected_year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55)
fig.update_layout(transition_duration=500)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
2. Dash HTML Components (html)
html
提供了一系列基本的 HTML 标签,如 Div
, H1
, P
, Table
, Img
等。
示例:使用 html.Div
布局
import dash
from dash import html
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Welcome to my app"),
html.P("This is some text."),
html.Table([
html.Tr([html.Td("A"), html.Td("B")]),
html.Tr([html.Td("C"), html.Td("D")])
])
])
if __name__ == '__main__':
app.run_server(debug=True)
3. Dash Layouts
你可以使用 html.Div
来组织其他组件,并通过 CSS 类来控制布局。
示例:使用 className
控制样式
import dash
from dash import html, dcc
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div("Some content", className="content"),
dcc.Dropdown(options=[{'label': 'Option 1', 'value': '1'}], value='1')
], className="container")
if __name__ == '__main__':
app.run_server(debug=True)
4. Dash Callbacks
回调是 Dash 应用的核心,它定义了前后端之间的交互逻辑。
示例:回调函数
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Input(id='input-box', type='text', value='Initial Text'),
html.Div(id='output-container')
])
@app.callback(
Output('output-container', 'children'),
[Input('input-box', 'value')]
)
def update_output(value):
return f'Input: "{value}"'
if __name__ == '__main__':
app.run_server(debug=True)
5. Stateful Callbacks
在某些情况下,你需要在回调之间保持状态,可以使用 State
对象。
示例:使用 State
import dash
from dash import dcc, html
from dash.dependencies import Input, Output, State
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Input(id='input-1', type='text', value='Montreal'),
dcc.Input(id='input-2', type='text', value='Canada'),
html.Button('Submit', id='button'),
html.Div(id='output-container')
])
@app.callback(
Output('output-container', 'children'),
[Input('button', 'n_clicks')],
[State('input-1', 'value'), State('input-2', 'value')]
)
def update_output(n_clicks, input1, input2):
return f'Input 1: "{input1}", Input 2: "{input2}"'
if __name__ == '__main__':
app.run_server(debug=True)
6. Dash Deployment
部署 Dash 应用通常涉及将其放置在一个 Web 服务器上。Plotly 提供了一个名为 Heroku 的免费平台来托管应用,但也可以使用其他的云服务提供商。
示例:使用 gunicorn
启动 Dash 应用
gunicorn my_dash_app:server
dash高级主题
- Dash Bootstrap Components (dbc):使用 Bootstrap 框架来美化你的 Dash 应用。
- Dash Interactivity:如何创建复杂的交互式应用。
- Dash Deployment with Docker:使用 Docker 来部署你的 Dash 应用。
- Dash Performance Optimization:提高 Dash 应用的性能。
- Dash Authentication and Security:保护你的 Dash 应用。
1. Dash Bootstrap Components (dbc)
Dash Bootstrap Components 是一个第三方库,它为 Dash 提供了一套基于 Bootstrap 4 的组件,可以让你的应用看起来更加专业和美观。
安装 Dash Bootstrap Components
pip install dash-bootstrap-components
示例:使用 dbc.Container
和 dbc.Row
import dash
from dash import html
import dash_bootstrap_components as dbc
app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.H1("Welcome to my app"), className="mb-5")
]),
dbc.Row([
dbc.Col(html.P("This is some text."), width=6),
dbc.Col(dbc.Card(dbc.CardBody("Card content")), width=6)
])
], fluid=True)
if __name__ == '__main__':
app.run_server(debug=True)
2. Dash Interactivity
Dash 允许你创建复杂的交互式应用,例如动态图表、响应式表格等。
示例:创建一个交互式图表
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/iris.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Dropdown(
id='xaxis-column',
options=[{'label': i, 'value': i} for i in df.columns[1:]],
value=df.columns[1]
),
dcc.Graph(id='indicator-graphic')
])
@app.callback(
Output('indicator-graphic', 'figure'),
[Input('xaxis-column', 'value')]
)
def update_graph(xaxis_column_name):
fig = go.Figure(data=[
go.Scatter(
x=df[df['species'] == species][xaxis_column_name],
y=df[df['species'] == species]['sepal_length'],
mode='markers',
name=species,
marker=dict(size=12, opacity=0.5)
) for species in df['species'].unique()
])
fig.update_layout(xaxis_title=xaxis_column_name, yaxis_title='Sepal Length')
return fig
if __name__ == '__main__':
app.run_server(debug=True)
3. Dash Deployment with Docker
使用 Docker 可以轻松地将你的 Dash 应用打包并部署到任何地方。
创建 Dockerfile
FROM python:3.8-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "-b", "0.0.0.0:8050", "app:server"]
构建 Docker 镜像
docker build -t my-dash-app .
运行 Docker 容器
docker run -p 8050:8050 my-dash-app
4. Dash Performance Optimization
为了提高 Dash 应用的性能,可以考虑以下几点:
- 使用 Dash Diskcache:将计算结果缓存到磁盘。
- 异步回调:使用 Dash 的异步回调功能来处理耗时的任务。
- 使用 Dash Pages:将大型应用拆分为多个页面。
示例:使用 Dash Diskcache
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
from dash_extensions.enrich import DiskcacheManager
import diskcache
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
app = dash.Dash(__name__, background_callback_manager=background_callback_manager)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app.layout = html.Div([
dcc.Dropdown(
id='country-dropdown',
options=[{'label': country, 'value': country} for country in df.country.unique()],
value='Canada'
),
dcc.Graph(id='country-graph')
])
@app.callback(
Output('country-graph', 'figure'),
[Input('country-dropdown', 'value')]
)
def update_graph(country):
filtered_df = df[df.country == country]
fig = px.line(filtered_df, x='year', y='lifeExp', title=f'Life Expectancy in {country}')
return fig
if __name__ == '__main__':
app.run_server(debug=True)
5. Dash Authentication and Security
为了保护你的 Dash 应用,可以使用以下方法:
- 使用 Dash Auth:内置的简单认证系统。
- HTTPS:确保所有通信都是加密的。
- 限制访问:仅允许授权 IP 地址访问应用。
示例:使用 Dash Auth
import dash
from dash import html
from dash_auth import BasicAuth
app = dash.Dash(__name__)
VALID_USERNAME_PASSWORD_PAIRS = {
'hello': 'world',
'test': 'test'
}
auth = BasicAuth(app, VALID_USERNAME_PASSWORD_PAIRS)
app.layout = html.Div([
html.H1("Secure Dash Application"),
html.P("Hello, world!")
])
if __name__ == '__main__':
app.run_server(debug=True)
- Dash Pages:如何使用 Dash Pages 来构建多页面应用。
- Dash URL Routing:如何处理 URL 路由和导航。
- Dash Extensions:如何利用 Dash Extensions 来扩展 Dash 的功能。
- Dash Data Tables:如何使用 DataTables 来展示和操作数据。
- Dash with Flask:如何将 Dash 应用集成到 Flask 框架中。
1. Dash Pages
Dash Pages 允许你创建具有多个页面的复杂应用。你可以使用 dash_pages
或者 dash_multipage
来实现这一点。
示例:使用 dash_pages
import dash
from dash import html, dcc
import dash_pages
app = dash.Dash(__name__, use_pages=True)
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
dash_pages.NavbarSimple(
brand="My App",
brand_href="/",
children=[
dash_pages.NavItem(dash_pages.NavLink("Page 1", href=dash_pages.get_page_url("page_1"))),
dash_pages.NavItem(dash_pages.NavLink("Page 2", href=dash_pages.get_page_url("page_2"))),
],
sticky="top",
),
dash_pages.PageContainer()
])
if __name__ == '__main__':
app.run_server(debug=True)
页面定义
每个页面通常定义在单独的 Python 文件中,例如 pages/page_1.py
和 pages/page_2.py
。
# pages/page_1.py
import dash
from dash import html
layout = html.Div([
html.H1('Page 1'),
html.P('This is the first page of the application.')
])
# pages/page_2.py
import dash
from dash import html
layout = html.Div([
html.H1('Page 2'),
html.P('This is the second page of the application.')
])
2. Dash URL Routing
Dash 支持 URL 路由,这意味着你可以根据不同的 URL 显示不同的页面或内容。
示例:使用 dash_pages
的路由
import dash
from dash import html, dcc
import dash_pages
app = dash.Dash(__name__, use_pages=True)
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
dash_pages.NavbarSimple(
brand="My App",
brand_href="/",
children=[
dash_pages.NavItem(dash_pages.NavLink("Home", href="/")),
dash_pages.NavItem(dash_pages.NavLink("Page 1", href=dash_pages.get_page_url("page_1"))),
dash_pages.NavItem(dash_pages.NavLink("Page 2", href=dash_pages.get_page_url("page_2"))),
],
sticky="top",
),
dash_pages.PageContainer()
])
if __name__ == '__main__':
app.run_server(debug=True)
3. Dash Extensions
Dash Extensions 是一系列额外的库,可以扩展 Dash 的功能。例如,dash_extensions
提供了额外的组件和功能,如 Lottie
动画、Camera
等。
示例:使用 dash_extensions
import dash
from dash import html, dcc
from dash_extensions.enrich import Lottie
import dash_extensions as de
app = dash.Dash(__name__)
app.layout = html.Div([
Lottie(options={"loop": True, "autoplay": True, "animationData": de.load_component_from_url("https://assets9.lottiefiles.com/packages/lf20_qc8w1z9y.json")}),
dcc.Slider(id='my-slider', min=0, max=100, value=50),
])
if __name__ == '__main__':
app.run_server(debug=True)
4. Dash Data Tables
Dash 提供了强大的 DataTables 组件,可以用来展示和操作数据。
示例:使用 dash_table.DataTable
import dash
from dash import html, dcc
from dash import dash_table
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict('records'),
editable=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
row_selectable="multi",
row_deletable=True,
selected_columns=[],
selected_rows=[],
page_action="native",
page_current=0,
page_size=10,
)
])
if __name__ == '__main__':
app.run_server(debug=True)
5. Dash with Flask
Dash 可以与 Flask 框架结合使用,这样可以方便地添加额外的路由和后端逻辑。
示例:使用 Flask 与 Dash 结合
from flask import Flask
import dash
from dash import html, dcc
from dash import dash_table
import pandas as pd
server = Flask(__name__)
app = dash.Dash(__name__, server=server, routes_pathname_prefix='/dash/')
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
app.layout = html.Div([
dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict('records'),
)
])
@server.route('/')
def home():
return "Welcome to the home page!"
if __name__ == '__main__':
server.run(debug=True)
- Dash Layouts:如何构建灵活的应用布局。
- Dash Callbacks:如何创建交互式回调函数。
- Dash State Management:如何管理和维护应用的状态。
- Dash Deployment:如何部署 Dash 应用到服务器上。
- Dash Security:如何保护你的 Dash 应用。
1. Dash Layouts
在 Dash 中,布局是通过组合 HTML 和 CSS 样式来构建的。你可以使用 Dash 的内置组件或者第三方库(如 dash_bootstrap_components
)来创建美观的界面。
示例:使用 dash_bootstrap_components
创建布局
import dash
from dash import html, dcc
import dash_bootstrap_components as dbc
app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.H1("Welcome to my Dash App!"), className="mb-2"),
dbc.Col(html.H6("A simple example layout"), className="mb-4")
]),
dbc.Row([
dbc.Col(dcc.Dropdown(['NYC', 'MTL', 'SF'], 'NYC', id='dropdown-selection'), width=2),
dbc.Col(dcc.Graph(id='line-plot'))
])
])
@app.callback(
dash.dependencies.Output('line-plot', 'figure'),
[dash.dependencies.Input('dropdown-selection', 'value')]
)
def update_graph(value):
# 假设你有一个包含数据的 DataFrame
df = pd.DataFrame({
'x': [1, 2, 3, 4, 5],
'y': [10, 20, 30, 40, 50]
})
figure = {
'data': [
{'x': df['x'], 'y': df['y'], 'type': 'line', 'name': value},
],
'layout': {
'title': 'Simple Line Plot'
}
}
return figure
if __name__ == '__main__':
app.run_server(debug=True)
2. Dash Callbacks
Dash 的核心功能之一是它的回调机制,它允许你在用户与应用交互时更新 UI 组件。
示例:创建一个简单的回调
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
app = dash.Dash()
app.layout = html.Div([
dcc.Input(id='input-box', type='text', value=''),
html.Button('Submit', id='button'),
html.Div(id='output-container-button',
children='Enter a value and press submit')
])
@app.callback(
Output('output-container-button', 'children'),
Input('button', 'n_clicks'),
Input('input-box', 'value')
)
def update_output(n_clicks, value):
if n_clicks is None:
return 'Enter a value and press submit'
else:
return f'Input value was "{value}", and the button has been clicked {n_clicks} times'
if __name__ == '__main__':
app.run_server(debug=True)
3. Dash State Management
在 Dash 中管理状态对于保持应用程序的一致性和响应性至关重要。你可以使用 State
对象来跟踪和管理状态。
示例:使用 State
更新组件
import dash
from dash import html, dcc
from dash.dependencies import Input, Output, State
app = dash.Dash()
app.layout = html.Div([
dcc.Input(id='input-1', type='text', value='Montreal'),
dcc.Input(id='input-2', type='text', value='Canada'),
html.Button(id='submit-button', n_clicks=0, children='Submit'),
html.Div(id='output-state')
])
@app.callback(
Output('output-state', 'children'),
Input('submit-button', 'n_clicks'),
State('input-1', 'value'),
State('input-2', 'value')
)
def update_output(n_clicks, input1, input2):
if n_clicks > 0:
return f'The Button has been pressed {n_clicks} times, '\
f'Input 1 is "{input1}", and Input 2 is "{input2}"'
else:
return ''
if __name__ == '__main__':
app.run_server(debug=True)
4. Dash Deployment
部署 Dash 应用到生产环境通常涉及选择一个合适的服务器,并配置必要的环境变量和依赖项。
示例:部署到 Heroku
- 将应用文件上传到 GitHub。
- 在 Heroku 上创建一个新的应用。
- 配置应用环境变量。
- 将代码推送到 Heroku Git 存储库。
- 使用 gunicorn 或其他 WSGI 服务器运行应用。
5. Dash Security
保护 Dash 应用的安全是非常重要的,这包括使用 HTTPS、设置身份验证以及防止跨站脚本攻击(XSS)等。
示例:使用基本的身份验证
import dash
from dash import html, dcc
from dash.exceptions import PreventUpdate
from flask import Flask, session
from flask_login import LoginManager, UserMixin, login_user, logout_user, current_user
import os
server = Flask(__name__)
app = dash.Dash(__name__, server=server)
server.config.update(
SECRET_KEY=os.urandom(12),
SESSION_COOKIE_HTTPONLY=True,
REMEMBER_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE='Strict',
)
login_manager = LoginManager()
login_manager.init_app(server)
login_manager.login_view = '/login'
class User(UserMixin):
def __init__(self, id):
self.id = id
@login_manager.user_loader
def load_user(user_id):
return User(user_id)
app.layout = html.Div([
dcc.Input(id='input-box', type='text', value=''),
html.Button('Submit', id='button'),
html.Div(id='output-container-button',
children='Enter a value and press submit')
])
@app.callback(
Output('output-container-button', 'children'),
Input('button', 'n_clicks'),
Input('input-box', 'value')
)
def update_output(n_clicks, value):
if not current_user.is_authenticated:
raise PreventUpdate
return f'Input value was "{value}", and the button has been clicked {n_clicks} times'
# 登录页面
@server.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if check_password(username, password): # 假设你有检查密码的函数
user = User(username)
login_user(user)
return redirect(url_for('index'))
return '''
<form method="post">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" value="Login">
</form>
'''
# 注销页面
@server.route('/logout')
def logout():
logout_user()
return redirect(url_for('login'))
if __name__ == '__main__':
app.run_server(debug=True)
以
- Dash Multi-Page Applications:如何构建具有多个页面的 Dash 应用。
- Dash with Flask:如何将 Dash 应用集成到 Flask 框架中。
- Dash Performance Optimization:如何优化 Dash 应用的性能。
- Dash Deployment:如何部署 Dash 应用到生产环境。
- Dash Security Best Practices:如何保护你的 Dash 应用免受安全威胁。
1. Dash Multi-Page Applications
在 Dash 中构建多页面应用可以通过多种方式实现,包括使用 dash_pages
或者 dash_multipage
等库。
示例:使用 dash_pages
创建多页面应用
import dash
from dash import html, dcc
import dash_pages
app = dash.Dash(__name__, use_pages=True)
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.H1("My Multi-Page App"),
dash_pages.NavbarSimple(
brand="My App",
brand_href="/",
children=[
dash_pages.NavItem(dash_pages.NavLink(page["name"], href=page["relative_path"]) for page in dash_pages.get_pages())
],
sticky="top",
),
dash_pages.PageContainer()
])
if __name__ == '__main__':
app.run_server(debug=True)
页面定义
每个页面通常定义在单独的 Python 文件中,例如 pages/page_1.py
和 pages/page_2.py
。
# pages/page_1.py
import dash
from dash import html
layout = html.Div([
html.H1('Page 1'),
html.P('This is the first page of the application.')
])
# pages/page_2.py
import dash
from dash import html
layout = html.Div([
html.H1('Page 2'),
html.P('This is the second page of the application.')
])
2. Dash with Flask
将 Dash 应用集成到 Flask 框架中可以让你充分利用 Flask 的路由和其他功能。
示例:使用 Flask 与 Dash 结合
from flask import Flask, render_template
import dash
from dash import html, dcc
import dash_bootstrap_components as dbc
server = Flask(__name__)
app = dash.Dash(__name__, server=server, url_base_pathname='/dash/')
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.H1("Welcome to my Dash App!"), className="mb-2"),
dbc.Col(html.H6("A simple example layout"), className="mb-4")
]),
dbc.Row([
dbc.Col(dcc.Dropdown(['NYC', 'MTL', 'SF'], 'NYC', id='dropdown-selection'), width=2),
dbc.Col(dcc.Graph(id='line-plot'))
])
])
@app.callback(
dash.dependencies.Output('line-plot', 'figure'),
[dash.dependencies.Input('dropdown-selection', 'value')]
)
def update_graph(value):
# 假设你有一个包含数据的 DataFrame
df = pd.DataFrame({
'x': [1, 2, 3, 4, 5],
'y': [10, 20, 30, 40, 50]
})
figure = {
'data': [
{'x': df['x'], 'y': df['y'], 'type': 'line', 'name': value},
],
'layout': {
'title': 'Simple Line Plot'
}
}
return figure
@server.route('/')
def home():
return render_template('home.html') # 假设你有一个 HTML 模板文件
if __name__ == '__main__':
server.run(debug=True)
3. Dash Performance Optimization
为了提高 Dash 应用的性能,可以采取以下措施:
- 使用 Dash Diskcache 来缓存计算结果。
- 使用异步回调来处理耗时的操作。
- 利用 Dash 的
no_initial_callback
选项来避免不必要的回调触发。
示例:使用 Dash Diskcache
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
from dash_extensions.enrich import DiskcacheManager
import diskcache
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
app = dash.Dash(__name__, background_callback_manager=background_callback_manager)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
4. Dash Deployment
部署 Dash 应用到生产环境通常涉及以下步骤:
- 选择一个合适的服务器或云服务提供商。
- 使用 Docker 容器化你的应用。
- 设置必要的环境变量和依赖项。
示例:使用 Docker 部署 Dash 应用
-
创建
Dockerfile
。 -
构建 Docker 镜像。
-
运行 Docker 容器。
Dockerfile
FROM python:3.8-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txtCOPY . .
CMD ["gunicorn", "-b", "0.0.0.0:8050", "app:server"]
构建 Docker 镜像:
docker build -t my-dash-app .
运行 Docker 容器:
docker run -p 8050:8050 my-dash-app
5. Dash Security Best Practices
为了保护你的 Dash 应用,应该遵循以下最佳实践:
- 使用 HTTPS 协议来加密通信。
- 设置身份验证以限制对应用的访问。
- 使用 CSRF 令牌来防止跨站请求伪造攻击。
- 确保敏感信息不会泄露给客户端。
示例:使用基本的身份验证
import dash
from dash import html, dcc
from dash_auth import BasicAuth
app = dash.Dash(__name__)
VALID_USERNAME_PASSWORD_PAIRS = {
'hello': 'world',
'test': 'test'
}
auth = BasicAuth(app, VALID_USERNAME_PASSWORD_PAIRS)
app.layout = html.Div([
html.H1("Secure Dash Application"),
html.P("Hello, world!")
])
if __name__ == '__main__':
app.run_server(debug=True, ssl_context='adhoc')
这些是 Dash 的一些高级主题和技术细节。如果你有任何具体问题或需要帮助的地方,请随时告诉我!
当然,我们可以继续深入探讨一些 Dash 的高级主题和技术细节。接下来我将介绍以下几点:
- Dash Advanced Callbacks:如何使用 Dash 的高级回调功能。
- Dash Custom Components:如何创建自定义的 Dash 组件。
- Dash with Pandas and DataFrames:如何在 Dash 中处理和展示数据。
- Dash with Plotly Express:如何使用 Plotly Express 创建交互式图表。
- Dash with Dash Pages:如何构建多页面的 Dash 应用。
1. Dash Advanced Callbacks
Dash 提供了一些高级回调功能,例如异步回调、多输出回调等。
示例:使用异步回调
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
from dash_extensions.enrich import Dash, Output, Input, State, callback, DiskcacheManager
import diskcache
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
app = Dash(__name__, background_callback_manager=background_callback_manager)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
2. Dash Custom Components
在 Dash 中,你可以创建自定义的组件来复用代码和简化布局。
示例:创建自定义组件
import dash
from dash import dcc, html
def CustomButton(id, label):
return html.Button(label, id=id, className="custom-button-style")
app = dash.Dash(__name__)
app.layout = html.Div([
CustomButton('my-button', 'Click Me'),
html.Div(id='output-container-button')
])
@app.callback(
dash.dependencies.Output('output-container-button', 'children'),
[dash.dependencies.Input('my-button', 'n_clicks')]
)
def update_output(n_clicks):
return f'The button has been clicked {n_clicks} times'
if __name__ == '__main__':
app.run_server(debug=True)
3. Dash with Pandas and DataFrames
Dash 可以轻松地与 Pandas 数据帧结合使用,以进行数据分析和展示。
示例:使用 Pandas DataFrame
import dash
from dash import dcc, html
import pandas as pd
import plotly.express as px
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id='gapminder-graph'),
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
)
])
@app.callback(
dash.dependencies.Output('gapminder-graph', 'figure'),
[dash.dependencies.Input('year-slider', 'value')]
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
4. Dash with Plotly Express
Plotly Express 是一个高级接口,用于快速创建交互式图表。
示例:使用 Plotly Express
import dash
from dash import dcc, html
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id='gapminder-graph'),
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
)
])
@app.callback(
dash.dependencies.Output('gapminder-graph', 'figure'),
[dash.dependencies.Input('year-slider', 'value')]
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
5. Dash with Dash Pages
Dash Pages 允许你构建多页面的应用。
示例:使用 Dash Pages
import dash
from dash import html, dcc
import dash_pages
app = dash.Dash(__name__, use_pages=True)
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.H1("My Multi-Page App"),
dash_pages.NavbarSimple(
brand="My App",
brand_href="/",
children=[
dash_pages.NavItem(dash_pages.NavLink(page["name"], href=page["relative_path"]) for page in dash_pages.get_pages())
],
sticky="top",
),
dash_pages.PageContainer()
])
if __name__ == '__main__':
app.run_server(debug=True)
页面定义
每个页面通常定义在单独的 Python 文件中,例如 pages/page_1.py
和 pages/page_2.py
。
# pages/page_1.py
import dash
from dash import html
layout = html.Div([
html.H1('Page 1'),
html.P('This is the first page of the application.')
])
# pages/page_2.py
import dash
from dash import html
layout = html.Div([
html.H1('Page 2'),
html.P('This is the second page of the application.')
])
Dash 的高级主题和技术细节
- Dash Server-Side Callbacks:如何使用 Dash 的服务器端回调功能。
- Dash with Flask and SQLAlchemy:如何将 Dash 与 Flask 和数据库结合使用。
- Dash with Plotly Graph Objects:如何使用 Plotly Graph Objects 创建图表。
- Dash with Dash Bio:如何使用 Dash Bio 库创建生物信息学应用。
- Dash with Dash Cytoscape:如何使用 Dash Cytoscape 创建网络图。
1. Dash Server-Side Callbacks
Dash 的服务器端回调功能允许你执行长时间运行的任务,并在后台处理这些任务。
示例:使用服务器端回调
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
from dash_extensions.enrich import Dash, Output, Input, State, callback, DiskcacheManager
import diskcache
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
app = Dash(__name__, background_callback_manager=background_callback_manager)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
2. Dash with Flask and SQLAlchemy
你可以将 Dash 与 Flask 和 SQLAlchemy 结合使用,以实现数据库操作。
示例:使用 Flask 和 SQLAlchemy
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
server = Flask(__name__)
app = dash.Dash(__name__, server=server)
server.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(server)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
db.create_all()
app.layout = html.Div([
dcc.Input(id='new-user-input', type='text', placeholder='New User'),
html.Button('Add User', id='add-user-button'),
html.Div(id='output-div')
])
@app.callback(
Output('output-div', 'children'),
Input('add-user-button', 'n_clicks'),
State('new-user-input', 'value')
)
def add_user(n_clicks, new_user):
if n_clicks is None:
return ''
else:
user = User(username=new_user, email=f'{new_user}@example.com')
db.session.add(user)
db.session.commit()
return f'User {new_user} added.'
if __name__ == '__main__':
server.run(debug=True)
3. Dash with Plotly Graph Objects
Plotly Graph Objects 提供了更多的灵活性和控制,以创建复杂的图表。
示例:使用 Plotly Graph Objects
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = go.Figure(data=go.Scatter(
x=filtered_df['gdpPercap'],
y=filtered_df['lifeExp'],
mode='markers',
marker=dict(size=filtered_df['pop']/100000, color=filtered_df['continent']),
text=filtered_df['country']
))
fig.update_layout(title=f'Gapminder Data for {year}',
xaxis_title='GDP per Capita',
yaxis_title='Life Expectancy',
showlegend=False)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
4. Dash with Dash Bio
Dash Bio 是一个专为生物信息学应用设计的库。
示例:使用 Dash Bio
import dash
from dash import html, dcc
import dash_bio as dashbio
import plotly.graph_objects as go
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id='sequence-viewer'),
dcc.Slider(
id='sequence-slider',
min=0,
max=1000,
step=1,
value=500
)
])
@app.callback(
Output('sequence-viewer', 'figure'),
Input('sequence-slider', 'value')
)
def update_sequence_viewer(position):
sequence = 'ATCG' * 250 # 生成一个简单的 DNA 序列
fig = go.Figure(data=[go.Scatter(x=list(range(len(sequence))), y=[1] * len(sequence), mode='markers',
marker=dict(color=[{'A': 'green', 'T': 'orange', 'C': 'blue', 'G': 'red'}[base] for base in sequence]))])
fig.update_layout(title=f'Sequence Viewer at Position {position}',
xaxis_title='Position',
yaxis_title='Nucleotide',
showlegend=False)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
5. Dash with Dash Cytoscape
Dash Cytoscape 是一个用于创建交互式网络图的库。
示例:使用 Dash Cytoscape
import dash
from dash import html, dcc
import dash_cytoscape as cyto
app = dash.Dash(__name__)
elements = [
{'data': {'id': 'one', 'label': 'Node 1'}},
{'data': {'id': 'two', 'label': 'Node 2'}},
{'data': {'source': 'one', 'target': 'two'}}
]
app.layout = html.Div([
cyto.Cytoscape(
id='cytoscape',
elements=elements,
style={'width': '100%', 'height': '450px'},
layout={'name': 'preset'}
)
])
if __name__ == '__main__':
app.run_server(debug=True)
当然可以。接下来,我们将探讨更多关于 Dash 的高级主题和技术细节。以下是几个额外的主题:
6. Dash with Plotly Express
Plotly Express 是一个用于快速创建交互式图表的高层 API。它提供了许多内置的图表类型,并且非常易于使用。
示例:使用 Plotly Express
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
7. Dash with Dash Bootstrap Components (DBC)
Dash Bootstrap Components (DBC) 是一个基于 Dash 和 Bootstrap 的 UI 组件库,它可以帮助你快速构建美观的用户界面。
示例:使用 DBC
import dash
import dash_bootstrap_components as dbc
from dash import html, dcc
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container([
html.H1("Gapminder Data Visualization"),
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
8. Dash with Pandas Profiling
Pandas Profiling 是一个用于自动数据质量报告的库。它可以很容易地集成到 Dash 中,为用户提供对数据集的深入理解。
示例:使用 Pandas Profiling
import dash
import dash_table
from dash import html, dcc
from dash.dependencies import Input, Output
import pandas as pd
import pandas_profiling
from jinja2 import Template
report = pandas_profiling.ProfileReport(df)
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Markdown(report.to_html(), dangerously_allow_html=True),
dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict('records'),
page_size=10
)
])
if __name__ == '__main__':
app.run_server(debug=True)
9. Dash with Dash AgGrid
Dash AgGrid 是一个用于展示表格数据的组件,它提供了很多功能,如排序、过滤等。
示例:使用 Dash AgGrid
import dash
from dash import html, dcc
from dash_ag_grid.AgGrid import AgGrid
import dash_ag_grid as dag
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
columnDefs = [{"field": c} for c in df.columns]
app.layout = html.Div([
AgGrid(
columnDefs=columnDefs,
rowData=df.to_dict('records'),
defaultColDef={"resizable": True, "sortable": True, "filter": True},
dashGridOptions={"rowSelection": "multiple"},
className="ag-theme-balham"
)
])
if __name__ == '__main__':
app.run_server(debug=True)
10. Dash with Flask Extensions
Flask 提供了许多扩展来增强其功能。例如,Flask-Caching 可以用来缓存昂贵的操作。
示例:使用 Flask-Caching
from flask import Flask
from flask_caching import Cache
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
server = Flask(__name__)
cache = Cache(server, config={'CACHE_TYPE': 'simple'})
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__, server=server)
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@cache.memoize(timeout=60)
def get_figure(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
return get_figure(year)
if __name__ == '__main__':
app.run_server(debug=True)
当然,我们可以继续深入探讨更多关于 Dash 的高级主题和技术细节。以下是几个额外的主题:
11. Dash with Flask-Security
Flask-Security 是一个用于 Flask 应用程序的安全模块,可以提供认证、角色管理等功能。它可以与 Dash 应用结合使用,为应用添加安全性。
示例:使用 Flask-Security
from flask import Flask
from flask_security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin, login_required
from flask_sqlalchemy import SQLAlchemy
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
app = dash.Dash(__name__)
server = app.server
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
# Flask-Security Configuration
app.config['SECRET_KEY'] = 'super-secret'
app.config['SECURITY_PASSWORD_SALT'] = 'super-secret-salt'
db = SQLAlchemy(app)
# Define models
roles_users = db.Table('roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
password = db.Column(db.String(255))
active = db.Column(db.Boolean())
confirmed_at = db.Column(db.DateTime())
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
# Create a user to test with
@app.before_first_request
def create_user():
db.create_all()
user_datastore.create_user(email='test@example.com', password='test')
db.session.commit()
# Add a login required decorator
@app.server.route('/secure-page')
@login_required
def secure_page():
return 'This is a secure page.'
if __name__ == '__main__':
app.run_server(debug=True)
12. Dash with Dash Leaflet
Dash Leaflet 是一个用于创建交互式地图的库。它可以与 Dash 应用结合使用,为用户提供地理空间数据的可视化。
示例:使用 Dash Leaflet
import dash
import dash_leaflet as dl
import dash_leaflet.express as dlx
from dash import html, dcc
from dash.dependencies import Input, Output
import geopandas as gpd
app = dash.Dash(__name__)
# Load GeoJSON data
gdf = gpd.read_file('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json')
# Convert GeoDataFrame to GeoJSON
geojson = dl.GeoJSON(data=gdf.to_json())
app.layout = html.Div([
dl.Map([dl.TileLayer(), geojson], center=[37, -102], zoom=4, style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"})
])
if __name__ == '__main__':
app.run_server(debug=True)
13. Dash with Dash Bio
Dash Bio 是一个专注于生物信息学应用的库,它提供了一系列用于分析和可视化生物数据的组件。
示例:使用 Dash Bio
import dash
from dash import html, dcc
import dash_bio as dashbio
import plotly.graph_objects as go
app = dash.Dash(__name__)
# Define a simple DNA sequence
sequence = 'ATCG' * 250
app.layout = html.Div([
dcc.Graph(id='sequence-viewer'),
dcc.Slider(
id='sequence-slider',
min=0,
max=len(sequence),
step=1,
value=len(sequence) // 2
)
])
@app.callback(
Output('sequence-viewer', 'figure'),
Input('sequence-slider', 'value')
)
def update_sequence_viewer(position):
fig = go.Figure(data=[go.Scatter(x=list(range(len(sequence))), y=[1] * len(sequence), mode='markers',
marker=dict(color=[{'A': 'green', 'T': 'orange', 'C': 'blue', 'G': 'red'}[base] for base in sequence]))])
fig.update_layout(title=f'Sequence Viewer at Position {position}',
xaxis_title='Position',
yaxis_title='Nucleotide',
showlegend=False)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
14. Dash with Dash Core Components (dcc)
Dash Core Components (dcc) 是 Dash 的一部分,提供了一系列交互式组件,如下拉列表、滑块等。
示例:使用 dcc
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
15. Dash with Dash DataTable
Dash DataTable 是一个用于展示表格数据的组件,支持排序、过滤等功能。
示例:使用 Dash DataTable
import dash
import dash_table
from dash import html, dcc
from dash.dependencies import Input, Output
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict('records'),
page_size=10
)
])
if __name__ == '__main__':
app.run_server(debug=True)
当然,让我们继续探讨一些其他高级主题和技术细节。接下来,我们将介绍以下几点:
16. Dash with Dash Plotly Components (dp)
Dash Plotly Components (dp) 是一个扩展库,提供了更多的组件和功能,特别是针对 Plotly 图表的定制和交互性。
示例:使用 dp
import dash
from dash import html, dcc
import dash_plotly_components as dp
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dp.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dp.Graph(id='gapminder-graph')
])
@app.callback(
dp.Output('gapminder-graph', 'figure'),
dp.Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
17. Dash with Dash Enterprise
Dash Enterprise 是 Plotly 提供的企业级解决方案,提供了更多的特性和支持,比如高性能的服务器、监控工具、部署工具等。
示例:使用 Dash Enterprise
Dash Enterprise 通常涉及到企业内部的部署和服务,因此示例代码可能不适用。但这里提供一个概览:
- 高性能服务器:利用 Dash Enterprise Server 来提升应用的性能。
- 监控工具:使用 Dash Enterprise Monitor 来监控应用的状态。
- 部署工具:使用 Dash Enterprise Deploy 来部署和管理应用。
18. Dash with Dash Material UI
Dash Material UI 是一个基于 Material Design 的 UI 组件库,用于构建现代且美观的用户界面。
示例:使用 Dash Material UI
import dash
from dash import html, dcc
import dash_materialui as dmui
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = dmui.AppBar(
position='static',
children=[
dmui.Toolbar(
children=[
dmui.IconButton(icon='menu'),
dmui.Typography(variant='h6', children='Gapminder Data Visualization'),
dmui.IconButton(icon='search'),
]
),
dmui.TabPanel(
value='tab1',
children=[
dmui.Slider(
id='year-slider',
min=df.year.min(),
max=df.year.max(),
value=df.year.min(),
marks={str(year): str(year) for year in df.year.unique()}
),
dcc.Graph(id='gapminder-graph')
]
)
]
)
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
19. Dash with Dash Bootstrap Themes
Dash Bootstrap Themes 提供了一系列预设的主题,可以快速改变应用的外观和感觉。
示例:使用 Dash Bootstrap Themes
import dash
import dash_bootstrap_components as dbc
from dash import html, dcc
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container([
html.H1("Gapminder Data Visualization"),
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
20. Dash with Dash Layout Components
Dash 提供了一系列布局组件,用于构建复杂的应用布局结构。
示例:使用 Dash Layout Components
import dash
from dash import html, dcc
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Gapminder Data Visualization"),
html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
], style={'width': '50%', 'float': 'left'}),
html.Div([
dcc.Markdown("## About"),
dcc.Markdown("This is a visualization of the Gapminder dataset.")
], style={'width': '50%', 'float': 'right'})
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
当然,让我们继续探讨一些其他高级主题和技术细节。接下来,我们将介绍以下几点:
21. Dash with Dash Lumen
Dash Lumen 是一个用于构建仪表板的框架,它提供了一个更简单的方式来组织和管理复杂的 Dash 应用。
示例:使用 Dash Lumen
import dash
import dash_lumen as dl
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
# Define a Lumen component
@dl.component
def YearSlider(id):
return dcc.Dropdown(
id=id,
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
)
# Define a Lumen layout
@dl.layout
def AppLayout():
return html.Div([
html.H1("Gapminder Data Visualization"),
YearSlider(id='year-slider'),
dcc.Graph(id='gapminder-graph')
])
app.layout = AppLayout()
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
22. Dash with Dash Gallery
Dash Gallery 是一个用于展示多个 Dash 应用的框架,可以帮助你组织和展示不同的应用实例。
示例:使用 Dash Gallery
import dash
import dash_gallery as dg
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
# Define a Dash Gallery component
@dg.component
def YearSlider(id):
return dcc.Dropdown(
id=id,
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
)
# Define a Dash Gallery layout
@dg.layout
def AppLayout():
return html.Div([
html.H1("Gapminder Data Visualization"),
YearSlider(id='year-slider'),
dcc.Graph(id='gapminder-graph')
])
app.layout = AppLayout()
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
23. Dash with Dash Enterprise
Dash Enterprise 是 Plotly 提供的企业级解决方案,提供了更多的特性和支持,比如高性能的服务器、监控工具、部署工具等。
示例:使用 Dash Enterprise
Dash Enterprise 通常涉及到企业内部的部署和服务,因此示例代码可能不适用。但这里提供一个概览:
- 高性能服务器:利用 Dash Enterprise Server 来提升应用的性能。
- 监控工具:使用 Dash Enterprise Monitor 来监控应用的状态。
- 部署工具:使用 Dash Enterprise Deploy 来部署和管理应用。
24. Dash with Dash Tabs
Dash Tabs 是一个用于创建标签式导航的组件,可以帮助用户在不同的视图之间切换。
示例:使用 Dash Tabs
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Tabs(id="tabs-example", value='tab-1', children=[
dcc.Tab(label='Tab one', value='tab-1'),
dcc.Tab(label='Tab two', value='tab-2'),
]),
html.Div(id='tabs-content-example')
])
@app.callback(Output('tabs-content-example', 'children'),
Input('tabs-example', 'value'))
def render_content(tab):
if tab == 'tab-1':
return html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
elif tab == 'tab-2':
return html.Div([
dcc.Markdown("## Tab Two Content"),
dcc.Markdown("This is the content for Tab Two.")
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
25. Dash with Dash Markdown
Dash Markdown 是一个用于渲染 Markdown 文档的组件,可以帮助你展示文档、说明等内容。
示例:使用 Dash Markdown
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
import dash_markdown as dmd
import markdown
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
markdown_text = """
# Gapminder Data Visualization
## Introduction
This is a simple visualization of the Gapminder dataset.
"""
app = dash.Dash(__name__)
app.layout = html.Div([
dmd.MarkdownEditor(id='markdown-editor', value=markdown_text),
html.Div(id='markdown-output'),
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('markdown-output', 'children'),
Input('markdown-editor', 'value')
)
def update_output(value):
return markdown.markdown(value)
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
当然,让我们继续探索更多关于 Dash 的高级主题和技术细节。接下来,我们将介绍以下几点:
26. Dash with Dash Cytoscape
Dash Cytoscape 是一个用于创建交互式网络图的组件,非常适合展示节点和边的关系。
示例:使用 Dash Cytoscape
import dash
from dash import html, dcc
import dash_cytoscape as cyto
import networkx as nx
app = dash.Dash(__name__)
# Generate a random graph using NetworkX
G = nx.random_geometric_graph(20, 0.125)
# Convert NetworkX graph to a list of nodes and edges
elements = [
{'data': {'id': n, 'label': n}} for n in G.nodes
] + [
{'data': {'source': u, 'target': v}} for u, v in G.edges
]
app.layout = html.Div([
cyto.Cytoscape(
id='cytoscape',
elements=elements,
layout={'name': 'circle'},
style={'width': '100%', 'height': '450px'}
)
])
if __name__ == '__main__':
app.run_server(debug=True)
27. Dash with Dash Jupyter
Dash Jupyter 是一个用于将 Dash 应用嵌入到 Jupyter Notebook 或 Jupyter Lab 中的库。
示例:使用 Dash Jupyter
import dash
from dash import html, dcc
from dash_jupyter import JupyterDash
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = JupyterDash(__name__)
app.layout = html.Div([
dcc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(mode='inline')
28. Dash with Dash SVG
Dash SVG 是一个用于渲染 SVG 图像的组件,可以帮助你展示矢量图形。
示例:使用 Dash SVG
import dash
from dash import html, dcc
from dash_svg import SVG
import plotly.express as px
import pandas as pd
app = dash.Dash(__name__)
# Define an SVG string
svg_string = '<svg width="100" height="100"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" /></svg>'
app.layout = html.Div([
SVG(svg_string, id='svg-example')
])
if __name__ == '__main__':
app.run_server(debug=True)
29. Dash with Dash React Components (drc)
Dash React Components (drc) 是一个提供 React 组件的库,可以让你在 Dash 应用中使用 React 组件。
示例:使用 drc
import dash
from dash import html, dcc
import dash_react_components as drc
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
drc.Dropdown(
id='year-slider',
options=[{'label': str(year), 'value': year} for year in df.year.unique()],
value=df.year.min()
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('year-slider', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
30. Dash with Dash React
Dash React 是一个用于在 Dash 应用中嵌入 React 组件的库。
示例:使用 Dash React
import dash
from dash import html, dcc
import dash_react as dr
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dr.ReactComponent(
id='react-component',
module='path/to/your/react/component',
props={
'options': [{'label': str(year), 'value': year} for year in df.year.unique()],
'value': df.year.min()
}
),
dcc.Graph(id='gapminder-graph')
])
@app.callback(
Output('gapminder-graph', 'figure'),
Input('react-component', 'value')
)
def update_graph(year):
filtered_df = df[df.year == year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent",
hover_name="country", log_x=True, size_max=55)
return fig
if __name__ == '__main__':
app.run_server(debug=True)