Dash+Plotly | Web应用开发(1)

本文为https://github.com/CNFeffery/DataScienceStudyNotes的学习笔记,部分源码来源于此仓库。
本期内容主要为基础概念web布局方法交互回调

文章目录

    • Dash的主要模块
    • Highlight
    • layout
    • callback
      • 惰性交互
      • 阻止初次回调
      • 忽略回调匹配错误
      • 控制部分回调输出不更新
      • 获取本轮回调的输入信息
      • 浏览器端执行回调

Dash的主要模块

  • dash.dcc(Dash Core Components)和dash_bootstrap_components提供核心的components,如按钮、下拉菜单等。
  • dash.html是对html标记语言的Python封装。可以将dccdbc中的组件放入html容器中
  • dash.Inputdash.Output是进行callback的必用组件
  • plotly.expressplotly.graph_objects是plotly的绘图库。一般将plotly画好的图像对象传入dcc.Graph()figure参数中。dcc.Graph()是dash渲染可交互图像的方法。
  • dash.dash_tabel是展示表格的对象,具有类似excel的功能。
import dash
from dash import Dash, html, dash_table, dcc, Input, Output
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objects as go

Highlight

  • layout: layout负责呈现前端的页面的布局,一般为dash.html模块中的对象。通过传入多个元素或多层嵌套,可以构建更复杂的页面内容。
  • callback: callback负责处理后端的数据交互。一般使用装饰器的形式,实现前后端异步通信交互。
  • 静态/交互部件: 静态部件主要为html中的组件,比如分割线静态图片等等。可交互的组件一般为dccdbc中的部件,它们通过callback实现通信交互。这些组件通过layout组织在一起,共同组成完整的Dash应用。
  • plotly图像: 理论上其他图像也可以放入Dash应用中,但作为Dash一奶同胞的兄弟,plotly天生可与Dash完美融合。
# 第一个Dash应用
# 展示一个Dash应用最基本的流程:实例化、添加组件、启动应用(实际上还有回调,后面会看到)from dash import Dash
import dash_html_components as html
import webbrowser# Dash实例化,所有Dash应用都应当如此
app = Dash(__name__,  # __name__不能省略external_stylesheets=['css/bootstrap.min.css']  # 规定了CSS的样式,这行是可选的)  app.layout = html.H1("第一个Dash应用")  # 在布局中添加组件if __name__ == '__main__':webbrowser.open("http://127.0.0.1:8050")  # 自动打开web应用。这句不是必须的,你可以手动打开。app.run_server()  # 启动你的Dash服务,在浏览器中打开http://127.0.0.1:8050/可以看到你的web页面。# 在终端中按下CTRL+C关闭服务

layout

dbc.Container()是组织页面布局的容器,它将页面看作N行12列的表格布局,通过设置component占多少列来设置组件的宽度。

行部件dbc.Row()组成列表传入dbc.Container()中,按照列表顺序从上至下排列。

列部件dbc.Col()组成列表传入行部件dbc.Row()中,按照列表顺序从左至右排列。

一个dbc.Row()中的部件宽度正好为12时充满整行,

小于12时右侧则会空出剩余的宽度,

大于12时将溢出的部件挤到下一行。

总而言之,嵌套等级为:Container() > Row() > Col()。如下所示:

app.layout = dbc.Container([dbc.Row(dbc.Col(html.Div("A single column"))),dbc.Row([dbc.Col(html.Div("One of three columns"),width=4),dbc.Col(html.Div("One of three columns"),width=4),dbc.Col(html.Div("One of three columns"),width=4),]),]
)

展示的效果:

img

ps:以上示例是官网展示的效果,但实际运行并未如期运行。知道原因大佬请指教。

  1. dbc.Row()可接受的常用参数还有justify,表示同一行的多个列元素设置对齐方式,可选项有'start''center''end''between'以及'around'五种

  2. dbc.Col()可接受的常用参数还有以下两个:

  • order: 代表同一个Row下的顺序。可接受的输入为:fristlast和1到12的整数,分别表示第一个,第十二个,和一到十二的任意一个位置。
  • offset: 代表对应Col()部件左侧增加对应的宽度,可接受的参数为1到12。

callback

每个component都有id,这是这个component的唯一索引。

callback一定是多个components之间的响应(有输入组件和输出组件),通过先输出,后输入的顺序传入对象。

  • 单个输入输出直接传入参数。
  • 多个输出输出,组成列表后再传入参数。只要有一个输入变化就会触发回调。

如下所示:

import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Outputapp = dash.Dash(__name__,external_stylesheets=['css/bootstrap.min.css']
)app.layout = html.Div([html.Br(),html.Br(),html.Br(),dbc.Container([dbc.Row([dbc.Col(dbc.Input(id='input-lastname'), width=3),dbc.Col(html.P('+'), width=1),dbc.Col(dbc.Input(id='input-firstname'), width=3),],justify='start'),html.Hr(),dbc.Label(id='output1'),html.Br(),dbc.Label(id='output2')])]
)# 回调以装饰器的形式声明
@app.callback([Output('output1', 'children'),  # 多输出时用列表的形式传入,单输出则可以直接传入。Output('output2', 'children')],  # Output中第一个参数为输出组件id,第二参数为做出响应的属性。[Input('input-lastname', 'value'),  # 多输入时用列表的形式传入,单输入则可以直接传入。Input('input-firstname', 'value')]  # Iutput中第一个参数为输出组件id,第二参数为需要监控的属性。
)
def input_to_output(lastname, firstname):  # 这里定义回调函数的具体内容try:return '完整姓名:' + lastname + firstname, f'姓名长度为{len(lastname+firstname)}'except:return '等待输入...', '等待输入...'  # 注意返回值,不是列表形式,多个元素直接返回即可if __name__ == '__main__':app.run_server()

惰性交互

以上的例子中,只要输入部件属性改变,回调函数会立马触发。

但有时我们不希望回调函数立马触发,而是在我们一声号令后(比如按下某个按钮),回调函数再触发,这样的回调称为惰性交互。

惰性交互实现非常简单,在callback中增加State()对象,如下所示:

import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State# 其余部分省略...@app.callback(Output('output-value', 'children'),Input('state-button', 'n_clicks'),  # 注意这里Input中的id是触发按钮。State('input-value', 'value')  # State中的id才是真正输入组件的id,# 相当于State替换了立即回调模式中的Input。
)
def input_to_output(n_clicks, value):if n_clicks:return value.upper()# 其余部分省略....

阻止初次回调

初次回调一般跟输入框有关系。因为首次打开的网页输入框都是空的,如果回调函数不支持空的输入就会产生错误。

callback中设置prevent_initial_call=True即可阻止初始回调,避免错误。

# 其余部分省略
@app.callback(Output('output1', 'children'),Input('input1', 'value'),prevent_initial_call=True  # 阻止初次回调
)
def callback1(value):return int(value) ** 2

忽略回调匹配错误

在很多时候,我们需要在发生某些交互回调时,才创建一些具有指定id的部件,如果在初始化时触发了回调,则会发生错误。

callback中设置suppress_callback_exceptions=True即可忽略回调时的id匹配错误,避免错误。

@app.callback(Output('output_desc', 'children'),Input('output_dropdown', 'options'),prevent_initial_call=True  # 忽略回调匹配错误
)
def callback2(options):pass

控制部分回调输出不更新

dash.no_update作为Output()的返回值,则对应的组件属性就不会更新。如:

# 其余部分省略@app.callback([Output('record-1', 'children'),Output('record-2', 'children'),Output('record-n', 'children'),],Input('button', 'n_clicks'),prevent_initial_call=True
)
def record_click_event(n_clicks):if n_clicks == 1:return ('第1次点击:{}'.format(time.strftime('%H:%M:%S', time.localtime(time.time()))),dash.no_update,  # 第1次点击, 2和3不参与回调dash.no_update)elif n_clicks == 2:return (dash.no_update,  # 第2次点击, 1和3不参与回调'第2次点击:{}'.format(time.strftime('%H:%M:%S', time.localtime(time.time()))),dash.no_update)elif n_clicks >= 3:return (dash.no_update,  # 3次及以上点击, 1和2不参与回调dash.no_update,'第3次及以上点击:{}'.format(time.strftime('%H:%M:%S', time.localtime(time.time()))),)

获取本轮回调的输入信息

多个输入的回调,一个输入部件就会触发回调。若想知道是哪个输入触发了回调,就要使用dash.callback_context

  • dash.callback_context.triggered: 字典;触发本轮回调组件的id和属性。
  • dash.callback_context.inputs: 字典;所有输入组件目前的id和属性。
@app.callback([Output('A-output', 'children'),Output('B-output', 'children'),Output('C-output', 'children'),Output('raw-json', 'children')],[Input('A', 'n_clicks'),Input('B', 'n_clicks'),Input('C', 'n_clicks')],prevent_initial_call=True
)
def refresh_output(A_n_clicks, B_n_clicks, C_n_clicks):# 获取本轮回调状态下的上下文信息ctx = dash.callback_context# 取出对应State、最近一次触发部件以及Input信息ctx_msg = json.dumps({'states': ctx.states,'triggered': ctx.triggered,'inputs': ctx.inputs}, indent=2)return A_n_clicks, B_n_clicks, C_n_clicks, ctx_msg

浏览器端执行回调

以上的回调是由服务器运算的,频繁触发会增加服务器压力。因此可以使用clientside_callbackClientsideFunction运行js脚本来将计算转移到浏览器端。示例省略(因为我不会JS)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/327848.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【VRTK】【VR开发】【Unity】19-VRTK实现旋转运动

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【背景】 在实际开发中,旋转运动也是时常需要模拟的重要运动类型。常见的场景有开关门,方向盘轮胎以及拉动拉杆等等。 旋转运动的实现可以基于物理系…

rust sqlx包(数据库相关)使用方法+问题解决

可以操作pgsql、mysql、mssql、sqlite 异步的,性能应该不错,具体使用有几个坑 除了sqlx库,还有对于具体数据库的库,比如postgres库 演示以pgsql为例,更新时间2024.1.6 官方github: sqlx github rust官方文档&#xff1…

常见Mysql数据库操作语句

-- DDL创建数据库结构 -- 查询所有数据库 show databases ; -- 修改数据库字符集 alter database db02 charset utf8mb4; -- 创建字符编码为utf——8的数据库 create database db05 DEFAULT CHARACTER SET utf8;-- 创建表格 create table tb_user(id int auto_increment primar…

ios 裁剪拼装图片

//1.获取图片UIImage *image [UIImage imageNamed:"123.jpg"];//处理图片//2.获取图片的长度long length image.size.width/4;//3.图片顶点索引long indices[] {length * 2,length,//右 right0,length,//左 leftlength,0,//上 toplength,length * 2,//底 bottomle…

【airsim】python控制airsim

使用airsim 1.8.1编译完成,进过block项目在cpp测试后,开始踩坑使用python。 使用AirSim\PythonClient\setup.py或者pip安装airsim。 python setup.py install或者 pip install airsim此时,windows电脑的环境信息 (air_py38) D:\code\Gith…

[技术杂谈]使用VLC将视频转成一个可循环rtsp流

通过vlc播放器,将一个视频转成rtsp流,搭建一个rtsp服务器。rtsp客户端可访问这个视频的rtsp流。 1. 打开vlc播放器,使用的版本如下 2. 菜单:媒体 ---> 流 3. 添加视频文件,点击添加一个mp4 文件 4. 选择串流&…

【gRPC学习】使用go学习gRPC

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 RPC是远程调用,而google实现了grpc比较方便地实现了远程调用,gRPC是一个现代的开源远程过程调用(RPC)框架 概念介绍 在gRPC中,客户端应用程序可以直接调用另一台计算机上的服务器应用程序上的方法&#…

记录汇川:H5U与Fctory IO 测试1

主程序: 子程序: Fctory IO通讯配置如下 : H5U作服务器,Fctory IO作客户端 这里参考:HU5作服务器地址 实现的动作如下: H5U与Factory IO联动

代码快递员:extern如何送达静态变量至各文件目的地

各位少年,大家好,我是博主那一脸阳光。 前言:话说有一天,静态变量先生和extern女士一起去参加编程界的武林大会。静态变量先生自豪地说:“你知道我为什么这么受欢迎吗?因为我可是个低调的富翁,我…

动态编译 - Dynamically Compile and Load External Java Classes

文章目录 概述Code 概述 动态编译和加载外部Java类的核心流程可以概括为以下几个步骤: 读取源代码: 首先,需要获取到外部的Java源代码。这通常是通过读取文件、网络资源或者数据库中的源代码字符串来实现的。编译源代码: 接下来,需要使用Ja…

html5实现好看的个人博客模板源码

文章目录 1.设计来源1.1 主界面1.2 认识我界面1.3 我的文章界面1.4 我的模板界面1.5 文章内容界面 2.结构和源码2.1 目录结构2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/135368653 html5实现好看…

物联网的感知层、网络层与应用层分享

物联网的概念在很早以前就已经被提出,20世纪末期在美国召开的移动计算和网络国际会议就已经提出了物联网(Internet of Things)这个概念。 最先提出这个概念的是MIT Auto-ID中心的Ashton教授,他在研究RFID技术时,便提出了结合物品编码、互联网…