กรอบ Dash

ในบทนี้เราจะพูดคุยเกี่ยวกับ Dash framework โดยละเอียด

Dash เป็นเฟรมเวิร์ก Python แบบโอเพนซอร์สที่ใช้สำหรับสร้างเว็บแอปพลิเคชันเชิงวิเคราะห์ เป็นไลบรารีที่มีประสิทธิภาพที่ช่วยลดความยุ่งยากในการพัฒนาแอปพลิเคชันที่ขับเคลื่อนด้วยข้อมูล เป็นประโยชน์อย่างยิ่งสำหรับนักวิทยาศาสตร์ข้อมูล Python ที่ไม่ค่อยคุ้นเคยกับการพัฒนาเว็บ ผู้ใช้สามารถสร้างแดชบอร์ดที่น่าทึ่งในเบราว์เซอร์โดยใช้แดช

สร้างขึ้นจาก Plotly.js, React และ Flask โดย Dash จะเชื่อมโยงองค์ประกอบ UI ที่ทันสมัยเช่นดรอปดาวน์แถบเลื่อนและกราฟเข้ากับโค้ด Python เชิงวิเคราะห์ของคุณโดยตรง

แอพ Dash ประกอบด้วยเซิร์ฟเวอร์ Flask ที่สื่อสารกับคอมโพเนนต์ Front-end React โดยใช้แพ็กเก็ต JSON ผ่านคำขอ HTTP

แอปพลิเคชัน Dash เขียนด้วย python ล้วนๆดังนั้นจึงไม่จำเป็นต้องใช้ HTML หรือ JavaScript

การตั้งค่า Dash

หากยังไม่ได้ติดตั้ง Dash ในเทอร์มินัลของคุณให้ติดตั้งไลบรารี Dash ที่กล่าวถึงด้านล่าง เนื่องจากไลบรารีเหล่านี้อยู่ระหว่างการพัฒนาให้ติดตั้งและอัปเกรดบ่อยๆ รองรับ Python 2 และ 3

  • pip install dash == 0.23.1 # แบ็กเอนด์ dash หลัก
  • pip install dash-renderer == 0.13.0 # dash front-end
  • pip install dash-html-components == 0.11.0 # คอมโพเนนต์ HTML
  • pip ติดตั้ง dash-core-components == 0.26.0 # คอมโพเนนต์ Supercharged
  • pip install plotly == 3.1.0 # Plotly graphing library

เพื่อให้แน่ใจว่าทุกอย่างทำงานอย่างถูกต้องที่นี่เราได้สร้างไฟล์ dashApp.py ง่ายๆ

Dash หรือ App Layout

แอพ Dash ประกอบด้วยสองส่วน ส่วนแรกคือ“ เค้าโครง” ของแอปซึ่งโดยพื้นฐานแล้วจะอธิบายลักษณะของแอปพลิเคชัน ส่วนที่สองอธิบายถึงการโต้ตอบของแอปพลิเคชัน

ส่วนประกอบหลัก

เราสามารถสร้างเค้าโครงด้วยไฟล์ dash_html_components และ dash_core_componentsห้องสมุด. Dash จัดเตรียมคลาส python สำหรับองค์ประกอบภาพทั้งหมดของแอปพลิเคชัน นอกจากนี้เรายังสามารถปรับแต่งส่วนประกอบของเราเองด้วย JavaScript และ React.js

นำเข้า dash_core_components เป็น dcc

นำเข้า dash_html_components เป็น html

dash_html_components มีไว้สำหรับแท็ก HTML ทั้งหมดที่ dash_core_components มีไว้สำหรับการโต้ตอบที่สร้างด้วย React.js

ใช้สองไลบรารีข้างต้นให้เราเขียนโค้ดตามที่ระบุด้านล่าง -

app = dash.Dash()
app.layout = html.Div(children=[
   html.H1(children='Hello Dash'),
   html.Div(children='''Dash Framework: A web application framework for Python.''')

และโค้ด HTML ที่เทียบเท่าจะมีลักษณะดังนี้ -

<div>
   <h1> Hello Dash </h1>
   <div> Dash Framework: A web application framework for Python. </div>
</div>

การเขียนแอพ Simple Dash

เราจะเรียนรู้วิธีการเขียนตัวอย่างง่ายๆบน dash โดยใช้ไลบรารีที่กล่าวถึงข้างต้นในไฟล์ dashApp.py.

# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()
app.layout = html.Div(children=[
   html.H1(children='Hello Dash'),
   html.Div(children='''Dash Framework: A web application framework for Python.'''),
	
   dcc.Graph(
      id='example-graph',
      figure={
         'data': [
            {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'Delhi'},
            {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Mumbai'},
         ],
         'layout': {
            'title': 'Dash Data Visualization'
         }
      }
   )
])

if __name__ == '__main__':
   app.run_server(debug=True)

เรียกใช้แอป Dash

สังเกตประเด็นต่อไปนี้ขณะเรียกใช้แอป Dash

(MyDjangoEnv) C: \ Users \ rajesh \ Desktop \ MyDjango \ dash> python dashApp1.py

  • ให้บริการแอป Flask "dashApp1" (ขี้เกียจโหลด)

  • สิ่งแวดล้อม: การผลิต

    คำเตือน: อย่าใช้เซิร์ฟเวอร์การพัฒนาในสภาพแวดล้อมการใช้งานจริง

    ใช้เซิร์ฟเวอร์ WSGI ที่ใช้งานจริงแทน

  • โหมดดีบัก: เปิด

  • เริ่มต้นใหม่ด้วยสถิติ

  • ดีบักเกอร์เปิดใช้งานอยู่!

  • PIN ดีบักเกอร์: 130-303-947

  • กำลังทำงานอยู่ http://127.0.0.1:8050/ (กด CTRL + C เพื่อออก)

127.0.0.1 - - [12/Aug/2018 09:32:39] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [12/Aug/2018 09:32:42] "GET /_dash-layout HTTP/1.1" 200 -
127.0.0.1 - - [12/Aug/2018 09:32:42] "GET /_dash-dependencies HTTP/1.1" 200 -
127.0.0.1 - - [12/Aug/2018 09:32:42] "GET /favicon.ico HTTP/1.1" 200 -
127.0.0.1 - - [12/Aug/2018 09:39:52] "GET /favicon.ico HTTP/1.1" 200 -

เยี่ยมชม http:127.0.0.1:8050/ในเว็บเบราว์เซอร์ของคุณ คุณควรเห็นแอปที่มีลักษณะเช่นนี้

ในโปรแกรมข้างต้นประเด็นสำคัญบางประการที่ควรสังเกตมีดังนี้ -

  • เค้าโครงแอปประกอบด้วยโครงสร้างของ "ส่วนประกอบ" เช่น html.Div และ dcc.Graph

  • ไลบรารี dash_html_components มีองค์ประกอบสำหรับทุกแท็ก HTML ส่วนประกอบ html.H1 (children = 'Hello Dash') สร้าง <h1> Hello Dash </h1> องค์ประกอบ HTML ในแอปพลิเคชันของคุณ

  • ส่วนประกอบทั้งหมดไม่ใช่ HTML ล้วนๆ dash_core_components อธิบายส่วนประกอบระดับสูงกว่าที่เป็นแบบโต้ตอบและสร้างด้วย JavaScript, HTML และ CSS ผ่านไลบรารี React.js

  • แต่ละองค์ประกอบอธิบายทั้งหมดผ่านแอตทริบิวต์คำหลัก Dash เป็นข้อมูลที่เปิดเผย: คุณจะอธิบายแอปพลิเคชันของคุณผ่านคุณลักษณะเหล่านี้เป็นหลัก

  • ทรัพย์สินสำหรับเด็กมีความพิเศษ ตามหลักการแล้วจะเป็นแอตทริบิวต์แรกเสมอซึ่งหมายความว่าคุณสามารถละเว้นได้

  • Html.H1 (children = 'Hello Dash') เหมือนกับ html.H1 ('Hello Dash')

  • แบบอักษรในแอปพลิเคชันของคุณจะดูแตกต่างจากที่แสดงที่นี่เล็กน้อย แอปพลิเคชันนี้ใช้สไตล์ชีต CSS ที่กำหนดเองเพื่อปรับเปลี่ยนรูปแบบเริ่มต้นขององค์ประกอบ รูปแบบตัวอักษรที่กำหนดเองได้รับอนุญาต แต่ ณ ตอนนี้เราสามารถเพิ่ม URL ด้านล่างหรือ URL ใดก็ได้ที่คุณเลือก -

    app.css.append_css ({“ external_url”:https://codepen.io/chriddyp/pen/bwLwgP.css}) เพื่อให้ไฟล์ของคุณมีรูปลักษณ์เหมือนกันกับตัวอย่างเหล่านี้

เพิ่มเติมเกี่ยวกับ HTML

ไลบรารี dash_html_components มีคลาสคอมโพเนนต์สำหรับทุกแท็ก HTML ตลอดจนอาร์กิวเมนต์คำสำคัญสำหรับอาร์กิวเมนต์ HTML ทั้งหมด

ให้เราเพิ่มสไตล์อินไลน์ของส่วนประกอบในข้อความแอพก่อนหน้าของเรา -

# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()
colors = {
   'background': '#87D653',
   'text': '#ff0033'
}

app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
   html.H1(
      children='Hello Dash',
      style={
         'textAlign': 'center',
         'color': colors['text']
      }
   ),
	
   html.Div(children='Dash: A web application framework for Python.', style={
      'textAlign': 'center',
      'color': colors['text']
   }),
	
   dcc.Graph(
      id='example-graph-2',

      figure={
         'data': [
            {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'Delhi'},
            {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Mumbai'},
         ],
         'layout': {
            'plot_bgcolor': colors['background'],
            'paper_bgcolor': colors['background'],
            'font': {
               'color': colors['text']
            }
         }
      }
   )
])

if __name__ == '__main__':
   app.run_server(debug=True)

ในตัวอย่างข้างต้นเราแก้ไขสไตล์อินไลน์ของคอมโพเนนต์ html.Div และ html.H1 ด้วยคุณสมบัติสไตล์

แสดงผลในแอปพลิเคชัน Dash ดังนี้ -

มีสองความแตกต่างที่สำคัญระหว่าง dash_html_components และแอตทริบิวต์ HTML -

  • สำหรับคุณสมบัติสไตล์ใน Dash คุณสามารถใส่พจนานุกรมได้ในขณะที่ใน HTML เป็นสตริงที่คั่นด้วยอัฒภาค

  • คีย์พจนานุกรมสไตล์คือ camelCasedดังนั้นการจัดแนวข้อความจึงเปลี่ยนเป็น textalign.

  • ClassName ใน Dash คล้ายกับแอตทริบิวต์คลาส HTML

  • อาร์กิวเมนต์แรกคือชายด์ของแท็ก HTML ซึ่งระบุผ่านอาร์กิวเมนต์คีย์เวิร์ดย่อย

ส่วนประกอบที่ใช้ซ้ำได้

ด้วยการเขียนมาร์กอัปของเราใน Python เราสามารถสร้างส่วนประกอบที่ใช้ซ้ำได้อย่างซับซ้อนเช่นตารางโดยไม่ต้องเปลี่ยนบริบทหรือภาษา -

ด้านล่างนี้เป็นตัวอย่างสั้น ๆ ที่สร้าง "ตาราง" จากดาต้าเฟรมของแพนด้า

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

df = pd.read_csv(
   'https://gist.githubusercontent.com/chriddyp/'
   'c78bf172206ce24f77d6363a2d754b59/raw/'
   'c353e8ef842413cae56ae3920b8fd78468aa4cb2/'
   'usa-agricultural-exports-2011.csv')
	
def generate_table(dataframe, max_rows=10):
   return html.Table(
      # Header
      [html.Tr([html.Th(col) for col in dataframe.columns])] +
      # Body
      [html.Tr([
         html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
      ]) for i in range(min(len(dataframe), max_rows))]
   )
	
app = dash.Dash()
app.layout = html.Div(children=[
   html.H4(children='US Agriculture Exports (2011)'),
   generate_table(df)
])

if __name__ == '__main__':
   app.run_server(debug=True)

ผลลัพธ์ของเราจะเป็นดังนี้ -

เพิ่มเติมเกี่ยวกับการแสดงภาพ

ไลบรารี dash_core_components มีส่วนประกอบที่เรียกว่า Graph.

กราฟแสดงภาพข้อมูลเชิงโต้ตอบโดยใช้ไลบรารีกราฟ JavaScript plotly.js แบบโอเพนซอร์ส Plotly.js รองรับแผนภูมิประมาณ 35 ประเภทและแสดงผลแผนภูมิทั้งใน SVG คุณภาพเวกเตอร์และ WebGL ประสิทธิภาพสูง

ด้านล่างนี้คือตัวอย่างที่สร้างพล็อตกระจายจากดาต้าเฟรมของ Pandas -

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go

app = dash.Dash()

df = pd.read_csv(
   'https://gist.githubusercontent.com/chriddyp/' +
   '5d1ea79569ed194d432e56108a04d188/raw/' +
   'a9f9e8076b837d541398e999dcbac2b2826a81f8/'+
   'gdp-life-exp-2007.csv')
	
app.layout = html.Div([
   dcc.Graph(
      id='life-exp-vs-gdp',
      figure={
         'data': [
            go.Scatter(
               x=df[df['continent'] == i]['gdp per capita'],
               y=df[df['continent'] == i]['life expectancy'],
               text=df[df['continent'] == i]['country'],
               mode='markers',
               opacity=0.7,
               marker={
                  'size': 15,
                  'line': {'width': 0.5, 'color': 'white'}
               },
               name=i
            ) for i in df.continent.unique()
         ],
         'layout': go.Layout(
            xaxis={'type': 'log', 'title': 'GDP Per Capita'},
            yaxis={'title': 'Life Expectancy'},
            margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
            legend={'x': 0, 'y': 1},
            hovermode='closest'
         )
      }
   )
])

if __name__ == '__main__':
   app.run_server()

ผลลัพธ์ของรหัสด้านบนมีดังนี้ -

กราฟเหล่านี้เป็นแบบโต้ตอบและตอบสนอง คุณสามารถวางเมาส์เหนือจุดต่างๆเพื่อดูค่าของสิ่งเหล่านั้นคลิกที่รายการในตำนานเพื่อสลับการติดตามคลิกและลากเพื่อซูมกด Shift ค้างไว้แล้วคลิกและลากเพื่อเลื่อน

Markdown

แม้ว่าเส้นประจะแสดงรสชาติ HTML ผ่านไลบรารี dash_html_components แต่การเขียนสำเนาของคุณใน HTML อาจเป็นเรื่องที่น่าเบื่อ สำหรับการเขียนบล็อคข้อความคุณสามารถใช้คอมโพเนนต์ Markdown ในไลบรารี dash_core_components

ส่วนประกอบหลัก

dash_core_components ประกอบด้วยชุดส่วนประกอบระดับสูงกว่าเช่นดรอปดาวน์กราฟมาร์กดาวน์บล็อกและอื่น ๆ อีกมากมาย

เช่นเดียวกับส่วนประกอบ Dash อื่น ๆ พวกเขาได้รับการอธิบายอย่างเปิดเผยทั้งหมด ทุกตัวเลือกที่สามารถกำหนดค่าได้จะพร้อมใช้งานเป็นอาร์กิวเมนต์คำสำคัญของคอมโพเนนต์

ด้านล่างนี้เป็นตัวอย่างโดยใช้ส่วนประกอบที่มีอยู่ -

# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

app.layout = html.Div([
   html.Label('Dropdown'),
   dcc.Dropdown(
      options=[
         {'label': 'New York City', 'value': 'NYC'},
         {'label': u'Montréal', 'value': 'MTL'},
         {'label': 'San Francisco', 'value': 'SF'}
      ],
      value='MTL'
   ),
	
   html.Label('Multi-Select Dropdown'),
   dcc.Dropdown(
      options=[
         {'label': 'New York City', 'value': 'NYC'},
         {'label': u'Montréal', 'value': 'MTL'},
         {'label': 'San Francisco', 'value': 'SF'}
      ],
      value=['MTL', 'SF'],
      multi=True
   ),
	
   html.Label('Radio Items'),
   dcc.RadioItems(
      options=[
         {'label': 'New York City', 'value': 'NYC'},
         {'label': u'Montréal', 'value': 'MTL'},
         {'label': 'San Francisco', 'value': 'SF'}
      ],
      value='MTL'
   ),
	
   html.Label('Checkboxes'),
   dcc.Checklist(
      options=[
         {'label': 'New York City', 'value': 'NYC'},
         {'label': u'Montréal', 'value': 'MTL'},
         {'label': 'San Francisco', 'value': 'SF'}
      ],
      values=['MTL', 'SF']
   ),

   html.Label('Text Input'),
   dcc.Input(value='MTL', type='text'),
	
   html.Label('Slider'),
   dcc.Slider(
      min=0,
      max=9,
      marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)},
      value=5,
   ),
], style={'columnCount': 2})

if __name__ == '__main__':
   app.run_server(debug=True)

ผลลัพธ์จากโปรแกรมด้านบนมีดังนี้ -

กำลังโทรขอความช่วยเหลือ

ส่วนประกอบ Dash มีการเปิดเผย ทุกส่วนที่กำหนดค่าได้ของส่วนประกอบเหล่านี้ถูกตั้งค่าระหว่างการติดตั้งเป็นอาร์กิวเมนต์คำสำคัญ คุณสามารถเรียกใช้ความช่วยเหลือในคอนโซล python บนส่วนประกอบใด ๆ เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับคอมโพเนนต์และอาร์กิวเมนต์ที่พร้อมใช้งาน บางส่วนได้รับด้านล่าง -

>>> help(dcc.Dropdown)
Help on class Dropdown in module builtins:
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)
| - options (list; optional): An array of options
| - value (string | list; optional): The value of the input. If `multi` is false (the default)
-- More --

เพื่อสรุปเค้าโครงของแอป Dash จะอธิบายลักษณะของแอป เค้าโครงเป็นแผนผังลำดับชั้นของส่วนประกอบ ไลบรารี dash_html_components จัดเตรียมคลาสสำหรับแท็ก HTML ทั้งหมดและอาร์กิวเมนต์คีย์เวิร์ดและอธิบายแอตทริบิวต์ HTML เช่น style, className และ id ไลบรารี dash_core_components สร้างส่วนประกอบระดับสูงขึ้นเช่นตัวควบคุมและกราฟ