热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

DashbyPlotly学习笔记

一、介绍1、dash是什么dash是一个基于Flask(Python)React的web框架。入门指南:https:dash.plot.lygetting-start

一、介绍

1、dash 是什么

dash 是一个基于 Flask (Python) + React 的 web 框架。

入门指南:https://dash.plot.ly/getting-started>

二、安装

1、安装

pip install dash==0.39.0 # The core dash backend
pip install dash-daq==0.1.0 # DAQ components (newly open-sourced!)

2、启动

$ python app.py

三、使用

1、基本框架

import dash

# init dash
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets) # create layout
app.layout = html.Div(children=[# ……
]),if __name__ == '__main__':# debug=True 激活所有开发工具,可选参数参考(https://dash.plot.ly/devtools)app.run_server(debug=True,dev_tools=)

2、组件

Declarative UI —— 声明式 UI

(1)html 元素

import dash_html_components as html

class/style 跟 react 的写法规范差不多。

# html.H1(children='Hello Dash') = html.H1('Hello Dash')html.H1('Hello Dash'),html.H1(id="h1-element", className='h1', children='Hello Dash',
style={'textAlign': 'center', 'color': '#7FDBFF'}),

布局

# 嵌套html.Div(children=[html.Div('111'),html.Div('222'),html.Div('333'),]),

# 12网格布局 html.Div(className='row', children=[html.Div('111', className='four columns'),html.Div('222', className='four columns'),html.Div('333', className='four columns'),]),# 更多预设 className 可以查看: https://codepen.io/chriddyp/pen/bWLwgP.css# tips:className='four columns' 其实是三列,className='three columns' 其实是四列,意思是用 12 除以它。

(2)python 封装的组件

import dash_core_components as dcc

import plotly.graph_objs as go

包括但不限于 单选框、下拉框、Markdown、Store、Graphs……,更多组件https://dash.plot.ly/dash-core-components

# draw Graphdcc.Graph(id='cluster_count',figure={'data': [go.Bar(x=[1,2,3],y=[100,200,300],text=['100个','200个','300个'],textposition='auto',)],'layout': go.Layout()},), # figure 属性下有 ”data“+"layout" 属性

它基于plotly.py画图库 https://plot.ly/python/,画图库又基于SVG和WebGL (默认为 SVG,对大型数据集会切换到WebGL)。

# 组件用法帮助
>>> help(dcc.Dropdown)

loading 组件

dcc.Loading执行回调的过程中会显示type属性设置的 loading 图标, 而回调完成后会显示children里的内容。

dcc.Loading(id="loading-1", children=[html.Div(id="loading-output-1")], type="default"),
dcc.Input(id="input-1", value='1'),@app.callback(Output("loading-output-1", "children"), [Input("input-1", "value")])
def input_triggers_spinner(value):time.sleep(1)return value

这里的回调@app.callback在下面会有介绍。

Interval 组件

dcc.Interval,interval设置间隔时间,n_intervals记录触发次数。

dcc.Interval(id='interval-component',interval=1*1000, # in millisecondsn_intervals=0)@app.callback(Output('interval-component-div', 'children'),[Input('interval-component', 'n_intervals')])
def update_metrics(n):return "Already run {} times".format(n)

(3)创建自己的组件

3、回调

Reactive Programming —— 反应式编程

from dash.dependencies import Input, Output, State

dcc.Input(id='my-input', value='initial value', type='text'),
dcc.Input(id='my-input-2', value='initial value', type='text'),
html.Button(id='submit-button', n_clicks=0, children='Submit'),
html.Div(id='my-div'),
html.Div(id='my-div-2') @app.callback([Output(component_id='my-div', component_property='children'),Output(component_id='my-div-2', component_property='children')],# 简写形式(省略 component_id + component_property)[Input('submit-button', 'n_clicks')],[State(component_id='my-input', component_property='value'),State(component_id='my-input-2', component_property='value')]
)
def update_output_div(n_clicks, input_value, input_value_2):return 'You\'ve entered "{}" and "{}"'.format(input_value, input_value_2), 'You\'ve click : "{}" times'.format(n_clicks)

注意事项(坑)

(1)每一个 callback 都会发送一个请求

(2)所有回调里的 Input 都必须有Output。

(3)同一个组件可以出现在多个回调的Input;但是在 Output 上,只能出现在一处回调里

(4)不支持组件的双向绑定

@app.callback(Output('my-id-2', 'value'),[Input('my-id', 'value')])
def aaa(data): print("11:"+data)return data @app.callback(Output('my-id', 'value'),[Input('my-id-2', 'value')])
def bbb(data): print("22:"+data)return data

官方说这个 feature 暂时没有解决,具体时间未知。详细讨论如下:

https://community.plot.ly/t/interdependent-components/8299/4

https://community.plot.ly/t/two-way-binding-for-rangeslider-and-input-fields-without-dependency-loop/4810

(5)在回调中共享数据

dash 有个原则就是Callbacks绝不能修改其范围之外的变量

但我们有时候需要用到共享数据,比如引入缓存机制来提高性能,这个时候应该怎么办呢?

方法一:存到当前用户的浏览器会话中(例如隐藏 DIV)

方法二:存到服务器磁盘上(例如文件或数据库)

方法三:存到服务器内存上(例如Redis)

持久化需要把数据序列化( 比如 toJSON() ),对于复杂的数据,推荐使用apache arrow

其中方法二和三可以使用Flask-Caching来实现。

pip install Flask-Caching

实现回调的缓存机制:

from flask_caching import Cachecache = Cache(app.server, config={'CACHE_TYPE': 'filesystem','CACHE_DIR': 'cache-directory'
})
# use redis
# 'CACHE_TYPE': 'redis',
# 'CACHE_REDIS_URL': os.environ.get('REDIS_URL', '')html.Div(id='flask-cache-memoized-children'),dcc.RadioItems(id='flask-cache-memoized-dropdown',options=[{'label': 'Option {}'.format(i), 'value': 'Option {}'.format(i)}for i in range(1, 4)],value='Option 1'),html.Div('Results are cached for {} seconds'.format(TIMEOUT)),@app.callback(Output('flask-cache-memoized-children', 'children'),[Input('flask-cache-memoized-dropdown', 'value')])
@cache.memoize(timeout=60) # in seconds
def render(value):return 'Selected "{}" at "{}"'.format(value, datetime.datetime.now().strftime('%H:%M:%S'))

896608-20190417180817826-1442195203.png

4、交互

只适用于dash_core_components

目前只支持四种交互方式: hoverData, clickData, selectedData, relayoutData

@app.callback(Output('click-data', 'children'),[Input('cluster_count', 'clickData')])
def display_click_data(clickData):return json.dumps(clickData, indent=2)

注意事项(坑)

(1)回调时的形参不能随意指定

@app.callback(Output('hover-data', 'children'),[Input('cluster_count', 'hoverData')])
# tips: 这里形参的hoverData不可以随便指定其他称呼,否则会获取不到值
def display_hover_data(hoverData):return json.dumps(hoverData, indent=2)

(2)暂不支持设置悬停和点击时的样式修改。

5、CSS & JS (& Header )

(1)外部文件(需手动引入)

# external_stylesheets
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css',{'href': 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css','rel': 'stylesheet','integrity': 'sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO','crossorigin': 'anonymous'}
]# external_scripts
external_scripts = ['https://www.google-analytics.com/analytics.js',{'src': 'https://cdn.polyfill.io/v2/polyfill.min.js'},{'src': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.core.js','integrity': 'sha256-Qqd/EfdABZUcAxjOkMi8eGEivtdTkh3b65xCZL4qAQA=','crossorigin': 'anonymous'}
]meta_tags = [{'name': 'description','content': 'My description'},{'http-equiv': 'X-UA-Compatible','content': 'IE=edge'}
]# init dash
app = dash.Dash(__name__, external_stylesheets=external_stylesheets,external_scripts=external_scripts,meta_tags=meta_tags)

(2)CDN文件(需手动引入)

app = dash.Dash(__name__,assets_external_path='http://your-external-assets-folder-url/'
)
app.scripts.config.serve_locally = False

(3) 本地文件(自动引入)

在根目录创建assets文件夹:

# 可以改这个设置
app.config.assets_folder = 'assets'

A、里面的 CSS/JS 文件会自动引入

B、IMG 图片需要这样加载html.Img(src='/assets/image.png'):

app.py
- assets/|-- typography.css|-- header.css|-- custom-script.js|-- image.png

6、路由


# ------------ 先定义 dcc.Location ,它的 pathname 属性会实时记录当前 url 的值 ------------dcc.Location(id='url', refresh=False), # 没有任何显示作用# ------------ 改变 url ------------# 会刷新页面
dcc.Link('Navigate to "/"', href='/'),
dcc.Link('Navigate to "/page-2"', href='/page-2'),# 不会刷新页面
html.A(href='/page-3',children='Navigate to "/page-3"'),# ------------ 改变 url 的 回调 ------------@app.callback(dash.dependencies.Output('page-content', 'children'),[dash.dependencies.Input('url', 'pathname')])
def display_page(pathname):return html.Div([html.H3('You are on page {}'.format(pathname))])

构建多页面应用程序

注意事项 (坑)

如果我们通过不同的 url去渲染不同的页面的话,会碰到一个问题,就是我们可能会率先定义了回调,而回掉中的组件暂时还没渲染到app.layout中,因此Dash会引发异常以警告我们可能做错了。在这种情况下,我们可以通过设置忽略该异常。即:

app.config.suppress_callback_exceptions = True

7、Auth

(1)HTTP Basic Auth

pip install dash-auth

896608-20190417180654482-1922149517.png

import dash_auth# Keep this out of source code repository - save in a file or a database
VALID_USERNAME_PASSWORD_PAIRS = [['hello', 'world']
]
auth = dash_auth.BasicAuth(app,VALID_USERNAME_PASSWORD_PAIRS
)app.scripts.config.serve_locally = True

(2)Plotly OAuth (需要付费)

8、部署

(1) 用 内嵌
(2)Flask 嵌入 Dash

(3)Dash 嵌入 Flask

延展知识

什么是 WSGI?

WSGI是仅针对 python 的 Web服务器网关接口(Python Web Server Gateway Interface)规范

注意,只是规范,是 web服务器和 web应用 之间的接口规范。

WSGI 跟 CGI 的区别?

CGI 是通用网关接口的规范,并不限于 Python 语言。虽然早已过时,后来分别诞生了 python 领域的 WSGI 和 php 的 FastCGI(PHP-FPM)等。

python 的 web 框架都要遵循这个规范,比如Flask内置的 wsgiref 或第三方的 Gunicorn 。 但前者 wsgiref 性能低下,所以推荐部署时选择 flask+Gunicorn+nginx 方案。

gunicorn --workers 6 --threads 2 app:server

—workers 指定进程数

—threads 指定线程数


参考资料

https://dash.plot.ly/

转:https://www.cnblogs.com/xjnotxj/p/10725268.html



推荐阅读
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • Java图形化计算器设计与实现
    本文介绍了使用Java编程语言设计和实现图形化计算器的方法。通过使用swing包和awt包中的组件,作者创建了一个具有按钮监听器和自定义界面尺寸和布局的计算器。文章还分享了在图形化界面设计中的一些心得体会。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有