一、介紹
Dash是一個用于建構Web應用程式的高效Python架構。
Dash寫在Flask,Plotly.js和React.js之上,非常适合在純Python中,使用高度自定義的使用者界面,建構資料可視化應用程式。它特别适合使用Python進行資料分析的人。
通過幾個簡單的模式,Dash抽象出建構基于Web的互動式應用程式所需的所有技術和協定。
Dash應用程式在Web浏覽器中呈現,可以将應用程式部署到伺服器,然後通過URL進行共享。
由于Dash應用程式是在Web浏覽器中進行檢視,是以Dash本質上是跨平台和移動端的。
Dash是一個開源庫,在許可的MIT下釋出,Plotly開發Dash,并提供了一個在企業環境中輕松部署Dash應用程式的平台。
二、應用場景
(一) 純Python建立互動式Web應用程式
Dash是用于建立Web應用程式的使用者界面庫,使用Python進行資料分析、資料探索、可視化、模組化、儀器控制和撰寫報告的人推薦使用。
使用Dash基于分析資料建構GUI非常簡單,下圖是一個43行代碼的Dash App示例,它将Dropdown與D3.js Plotly Graph結合起來使用。當使用者在下拉清單中選擇一個值時,應用程式代碼會将Google财經中的資料動态導出到Pandas DataFrame中,并進行可視化(源代碼)。
Dash應用程式的代碼,非常靈活簡單,可以很友善地建構包含許多互動元素的複雜應用程式。下圖是一個包含5個輸入,3個輸出和交叉濾波的示例,隻有160行代碼,所有代碼都是Python寫的(源代碼)。
應用程式的每個元素都可以自定義:大小,位置,顔色和字型等。Dash應用程式是在Web中建構和釋出的,是以CSS的全部功能都可用。下圖是一個高度定制的互動式Dash報告應用程式的示例,其中包含Goldman Sachs報告的品牌和風格(源代碼)。
雖然在Web浏覽器中檢視Dash應用程式,但不必編寫任何Javascript或HTML。Dash為一組豐富的基于Web的互動式元件提供了Python接口。
import dash_core_components as dcc
dcc.Slider(value=4, min=-10, max=20, step=0.5,
marks={-5: '-5 Degrees', 0: '0', 10: '10 Degrees'})
Dash提供了一個簡單的回調裝飾器,用于将自定義資料分析代碼綁定到Dash使用者界面,實作進階互動,如下簡單示例。
@dash_app.callback(Output('graph-id', 'figure'), [Input('slider-id', 'value')])
def your_data_analysis_function(new_slider_value):
new_figure = your_compute_figure_function(new_slider_value)
return new_figure
當元素的值發生變化時,比如選擇下拉菜單或拖動滑塊,Dash的回調裝飾器會把新的元素值傳遞給Python代碼,進行互動操作,比如:篩選Pandas的DataFrame、執行SQL查詢語句、運作模拟、執行運算,或開始試驗等。進而更新UI中指定元素的屬性值,包括:圖表、表格、文本等,實作高度互動。
下面的例子簡要展示了文本框與圖形的互動更新,此代碼基于目前標明的點,在Pandas的DataFrame中篩選資料(源代碼)。
下面的示例中,當滑鼠在圖形元素的點上懸停時,可以顯示相關藥物的元資訊;在多選式下拉菜單中添加内容時,還可以向表格中追加行。
通過兩個抽象大類:Python元件和回調函數裝飾器,Dash抽象出基于Web的互動式應用程式所需的所有技術和協定。
(二) 體系架構
1. Flask和React
Dash應用程式是運作Flask,并通過HTTP請求傳遞JSON資料包的Web伺服器。Dash的前端使用React.js渲染元件,React.js是由Facebook編寫和維護的Javascript使用者界面庫。
Flask很棒,已被Python社群廣泛采用,并部署于衆多生産環境中。Dash應用的開發者可以設定Flask的底層執行個體和屬性,進階開發者還可以使用衆多的Flask插件擴充Dash應用。
React也很贊,在Plotly,我們用React重寫了全部Web平台和線上視圖編輯器。React最了不起的一點是它的社群作品衆多且個個優秀。React的開源社群已經公布了數以千計的高品質互動式元件,包括下拉菜單、滑塊、月曆,還有互動式表格等。
Dash整合了Flask與React的強大功能,使非專業Web開發的Python資料分析師也可以使用。
2. 從React.js到Python Dash元件
Dash元件是一個編譯React元件屬性與值,并将之生成JSON序列的Python類。
Dash提供了一個工具集,可以輕松地将React元件 (Javascript編寫) ,打包為可在Dash中使用的元件。此工具集使用動态程式設計,自動将注釋過的React PropType轉化為标準的Python類。生成後的Dash元件Python類對使用者很友好,能進行自動參數驗證,并生成字元串。
動态生成的參數驗證示例:
>>> import dash_core_components as dcc
>>> dcc.Dropdown(valu=3)
Exception: Unexpected keyword argument `valu`
Allowed arguments: id, className, disabled, multi, options, placeholder, value
動态生成的元件文檔示例:
>>> help(dcc.Dropdown)
class Dropdown(dash.development.base_component.Component)
| A Dropdown component.
| Dropdown is an interactive dropdown element for selecting one or more
| items.
| The values and labels of the dropdown items are specified in the `options`
| property and the selected item(s) are specified with the `value` property.
|
| Use a dropdown when you have many options (more than 5) or when you are
| constrained for space. Otherwise, you can use RadioItems or a Checklist,
| which have the benefit of showing the users all of the items at once.
|
| Keyword arguments:
| - id (string; optional)
| - className (string; optional)
| - disabled (boolean; optional): If true, the option is disabled
| - multi (boolean; optional): If true, the user can select multiple values
| - options (list; optional)
| - placeholder (string; optional): The grey, default text shown when no option is selected
| - value (string | list; optional): The value of the input. If `multi` is false (the default)
| then value is just a string that corresponds to the values
| provided in the `options` property. If `multi` is true, then
| multiple values can be selected at once, and `value` is an
| array of items with values corresponding to those in the
| `options` prop.
|
| Available events: 'change
全套的HTML标記,如
、等,由React進行動态渲染,均由dash_html_component庫提供。
下拉菜單、圖形、滑塊等核心互動式元件由Dash核心團隊通過dash_core_components庫提供。
如果自行編寫元件庫(教程),可使用上述的兩個庫,調用開源的标準React-to-Dash工具鍊進行支援。
3. 并發-多使用者應用
Dash應用程式的狀态存儲在前端(即Web浏覽器)中,這允許多個使用者可以使用獨立的會話,同時與Dash應用程式進行互動操作。
4. CSS和預設樣式
核心庫沒有包含CSS與預設樣式,這樣做是為了支援子產品化和獨立版本控制,鼓勵Dash應用的開發者,自定義其應用程式的界面外觀。點此查閱由Dash核心團隊維護的核心樣式指南。
5. 資料可視化
Dash的圖形元件使用plotly.js對圖形進行渲染,Plotly.js與Dash配合默契,它使用聲明式程式設計模式,開源且速度快,還支援科技計算、金融、商務類的各種視圖。Plotly.js基于D3.js建構,支援導出符合出版标準的高清矢量圖與優先性能的WebGL視圖。
Dash的圖形元素與開源的plotly.py庫共享同樣的文法,開發者可以輕易地在兩者之間切換。Dash的圖形元件從plotly.js事件系統中關聯資訊,允許開發者編寫響應在Plotly圖形中懸停、點選、選點等操作的應用。
6. 開源存儲庫
(三) 現有技術
Dash是Python生态系統中的新功能,但支撐它的理念與驅動力已在不同語言和應用中存續了數十年。
如果你是從Excel陣營中轉移過來的,那算是來對地方了。Dash與Excel都采用了“響應式”的程式模型。在Excel中,輸入單元格發生變化時,輸出單元格也會自動更新。任何單元格都可以是輸出,輸入或兩者。
輸入單元格并不關注哪些輸出單元格依賴于它們,是以添加新的輸入單元格或連接配接一系列單元格變得非常友善,如下是一個Excel 應用:
下面的例子是用Dash實作了類似Excel的效果。用滑塊、輸入框、下拉菜單與圖形等豐富的Web元件,取代Excel中的單元格,用Python代碼取代Excel函數或VBA腳本。
app.layout = html.Div([
html.Label('Hours per Day'),
dcc.Slider(id='hours', value=5, min=0, max=24, step=1),
html.Label('Rate'),
dcc.Input(id='rate', value=2, type='number'),
html.Label('Amount per Day'),
html.Div(id='amount'),
html.Label('Amount per Week'),
html.Div(id='amount-per-week')
])
@app.callback(Output('amount', 'children'),
[Input('hours', 'value'), Input('rate', 'value')])
def compute_amount(hours, rate):
return float(hours) * float(rate)
@app.callback(Output('amount-per-week', 'children'),
[Input('amount', 'children')])
def compute_amount(amount):
return float(amount) * 7
即便在科學計算和量化金融領域,Excel仍屬主流,這并不隻是技術能力的問題,畢竟不少電子表格開發者的Excel、VBA,甚至SQL水準都很高。
Excel電子表格比Python程式更容易共享,并且編輯Excel單元格比指令行參數更友善。
但是,在Excel中模組化還是有很多局限性:電子表格經常會變的越來越大,越大就越不穩定,越難移植到生産環境,也很難進行審查、測試和維護。
希望使用Dash能夠更輕松地開發Python資料分析項目,通過共享同樣的函數式與響應式原則,編寫Dash應用幾乎和編寫電子表格一樣簡單,而且還更強大、更易于展示。
如果你使用R語言開發,那你很幸運。Shiny是一個反應式程式設計架構,用于在純R中生成Web應用程式,甚至可以使用Shiny和Plotly的R庫建立互動式圖形。Dash和Shiny相似,但Dash不會成為Shiny的複制品,畢竟Python和R之間的習語與理念非常不同,所使用的文法也不同。
如果你使用MATLAB開發,那一定熟悉MATLAB的使用者界面“GUIDE”。Mathworks可以說是科學計算的鼻祖,要知道GUIDE是2004開發的,那可是十多年之前!
如果你使用資料庫管理資料,可以使用Tableau或其它BI工具。Tableau很了不起,它提高了業界對資料分析的期望值,即終端使用者應該可以自主分析,并能夠直接使用工具探索資料。它還使得“向下鑽取”和“交叉過濾”這樣的概念變得流行。
Dash是這些BI工具的補充,這些工具非常适合結構化資料。但是,當進行資料轉換和分析時,很難超越Python等程式設計語言和社群的廣度和靈活性。Dash在建構使用者界面時抽象出許多複雜性,使你能夠為自定義資料分析後端建構漂亮的前端。
最後,我要給Jupyter Widget(小元件)點贊,Jupyter在其Notebook界面中提供了一個非常贊的Widget架構,可以為在本地運作的Jupyter Notebook中的圖形添加滑塊等功能。
Dash中的小部件類似于Jupyter中的小部件。在Jupyter Notebook中,可以直接使用代碼添加Widget。在Dash中,代碼與控件和應用是分開的,因為Dash的目标是開發易于分享的應用,而不是代碼或筆記。你可以混搭使用這些工具,也可以在Jupyter Notebook環境中編寫Dash應用。
我們也是nteract項目的忠實粉絲,它将Jupyter Notebook打包成一個桌面程式,大大地降低了使用Python和Jupyter Notebook的門檻。
三、許可和開源商業模式
Plotly是一家由VC支援的創業公司,成立于2013年,并于2015年開放了核心技術plotly.js(麻省理工學院許可證),在Python,R和MATLAB中維護開源庫,與plotly.js和web應用程式進行連接配接,用于建立各種圖表并将它們連接配接到資料庫(連接配接器也是開源的)。
Plotly提供了針對視圖托管、共享平台、視圖編輯與資料庫查詢應用的訂閱,這個平台适用于Web,也可在本地部署。
Plotly還提供了Dash的更新版,Dash支援MIT許可證,可以免費使用和修改。企業使用者則可選擇Dash企業版,可以輕松地在企業防火牆的保護下在伺服器端釋出和配置Dash應用。
Dash企業版的目标是在企業内部輕松、安全地共享Dash應用。不需要開發人員,它可以處理URL路由、監控、錯誤處理、部署、版本控制和包管理等操作,通過企業的活動目錄 (Active Directory) 或 LADP 使用者賬戶可以對部署的Dash企業版應用進行配置。
如果僅在本地使用開源版本,則沒有任何限制,還可以通過Heroku或Digital Ocean等平台自行管理Dash應用程式的部署。如果有足夠的财力,最好購買支援計劃,Plotly的工程師将提供一對一的幫助。如需其它定制服務或實作特定功能,請了解進階開發計劃。
對于産品型公司而言,開源仍是個新課題。但最終,我們能夠将超過一半的員工奉獻給開源産品。非常感謝迄今為止支援Plotly的所有人❤️