오늘 할 일: 끝내주게 숨쉬기
article thumbnail

최근에 프로젝트를 수행하던 중, 머신러닝 모델의 결과를 실시간으로 확인하기 위해 웹을 개발해야할 필요가 생겼다. 단순하게 시나리오를 이용해 입력값이 이렇게 들어가면 결과가 이렇습니다! 라며 캡처를 통해 보여줄 수도 있었다. 그래도 웹을 좀 이용해서 실제 서비스처럼 보여주면 더 좋을 것 같다는 의견에 따라 화면 개발을 시작했다. 웹 개발은 당연히 해본 적은 없지만.. dash 라이브러리를 이용하면 파이썬에서도 쉽게 구축할 수 있다고 해서 도전~~!  

 

 

dash 소개

 

Dash는 호작용하는 웹 어플리케이션을 만드는 데 사용되는 파이썬 프레임워크이다. plotly에서 만들었으며, Flask, Plotly.js와 React.js 라이브러리 위에서 작성된다. 웹 개발을 위해 사용된다고 알려진 HTML, CSS 혹은 자바스크립트를 알 필요가 없어 편리하다.

 

출처: http://bigdata.dongguk.ac.kr/lectures/datascience/_book/a4.-dash%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-python-dashboard.html

https://dash.plotly.com/dash-enterprise

 

Dash Enterprise | Dash for Python Documentation | Plotly

 

dash.plotly.com

 

 

dash 구성요소

 

Dash는 크게 레이아웃콜백 2가지 요소로 이루어져있다.

 

레이아웃(layout)

레이아웃은 어플리케이션의 UI(사용자 인터페이스: User Interface)를 구성하는 요소이다. 다양한 라이브러리들을 이용하여 UI를 다채롭게 구성할 수 있다.

  • dash_html_components: HTML 태그와 관련한 구성 요소를 제공
  • dash_core_components: 마크다운, 입력필드, 버튼, 드롭다운, 체크박스, 그래프 등과 같은 대화형 구성 요소를 제공
  • dash_table: 데이터에 대한 테이블 뷰어를 제공

 

콜백(callback)

콜백은 어플리케이션을 대화형(interactive)으로 만드는 논리를 함수로 구현한 요소이다. 사용자의 입력에 반응을 하며 값이 변경될 때마다 자동으로 호출된다. 사용자의 입력을 input으로 받고, 그 input을 특정 함수에 넣어 얻은 output을 업데이트하여 사용자에게 제공한다.

 

 

Dash 활용 예제

 

사용 라이브러리

파이썬은 3.7.4 버전을 사용하였으며 예제에서 사용한 라이브러리들과 각각의 버전은 아래와 같다.

Package Version
dash 2.7.0
plotly 5.11.0
pandas 1.1.1

 

사용 데이터

아래 예제에서는 서울시 공동주택 아파트 정보를 활용하였다. 데이터는 서울 열린 데이터 광장에서 다운로드 받았다. 이 데이터에는 서울 시내에 있는 아파트의 아파트명, 단지분류(아파트, 주상복합, 연립주택 등), 주소, 복도유형 등에 대한 정보가 있다. 

https://data.seoul.go.kr/dataList/OA-15818/S/1/datasetView.do

 

열린데이터광장 메인

데이터분류,데이터검색,데이터활용

data.seoul.go.kr

 

 

데이터 이해를 위해 아래와 같이 생겼음을 확인하고 넘어가겠다.

import pandas as pd

data = pd.read_csv("./data/서울시 공동주택 아파트 정보.csv", encoding="cp949")
data = data.loc[:, [
    "k-아파트명", "k-단지분류(아파트,주상복합등등)", "주소(시군구)", "주소(읍면동)", 
    "k-복도유형", "k-난방방식", "k-전체세대수", "주차대수", "좌표X", "좌표Y"]]
data.columns = ["아파트명", "단지분류", "시군구", "읍면동", "복도유형", "난방방식", "세대수", "주차대수", "좌표X", "좌표Y"]
data.head()

 

layout

먼저 간단하게 레이아웃 구성만을 이용하여 어플리케이션을 구성하는 코드를 작성해보았다.

import plotly.express as px
from dash import Dash, dcc, html

import pandas as pd

# 앱 초기화
app = Dash(__name__)

# preprocess
data = pd.read_csv("./data/서울시 공동주택 아파트 정보.csv", encoding="cp949")
data = data.loc[:, [
    "k-아파트명", "k-단지분류(아파트,주상복합등등)", "주소(시군구)", "주소(읍면동)", 
    "k-복도유형", "k-난방방식", "k-전체세대수", "주차대수", "좌표X", "좌표Y"]]
data.columns = ["아파트명", "단지분류", "시군구", "읍면동", "복도유형", "난방방식", "세대수", "주차대수", "좌표X", "좌표Y"]

# 그래프 정의
fig = px.box(
    data, x="시군구", y="세대수"
)

# 레이아웃 정의
app.layout = html.Div(children=[
    html.H1(
        children="서울시 공동주택 아파트 정보",
        style={"textAlign": "center"}
    ),
    html.H4(
        children="시군구별 세대수 분포", 
    ),
    dcc.Graph(
        id="graph",
        figure=fig
    ),
], style={"width": "90%", "margin": "auto"})

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

 

레이아웃은 html.Div를 사용하여 설정한다. Div는 일종의 래퍼로써, 제목이나 그래프와 같은 요소들을 Div 내에서 정의하여 레이아웃을 구성할 수 있다.  Div는 id(요소의 고유 식별자), style(너비, 높이, 색상 등을 설정할 수 있음), children(하위요소, 자식요소)과 같은 인수를 포함할 수 있다. children에서 렌더링하고자 하는 내용들을 정의하여 사용한다. 

 

위 코드에서는 H1(헤더와 같은 가장 큰 문자를 작성할 때 사용)와 H4(숫자가 클수록 문자의 크기가 작아짐), dcc(dash core components)의 Graph를 정의하여 어플리케이션을 작성하였다. 그래프는 레이아웃을 정의하기 전에 미리 할당한 정보(시군구별 세대수 boxplot)를 사용한다.

 

위 코드를 포함하는 py 파일을 작성하여 cmd에서 작동시키면 url이 나타나며, url을 클릭하여 작성한 코드가 웹으로 구현됨을 확인할 수 있다.

 

callback

위 예시는 이미 하나로 정의된 그래프를 출력만 하는 어플리케이션이다. dash를 활용하는 이유는 사용자와의 상호작용에 따른 결과를 보기 위함이었으니, 이제 콜백을 사용해서 이 과정을 구현해보겠다. 사용자가 dropdown을 통해 특정 시군구를 하나 선택하면, 해당 시군구의 세대수 boxplot을 확인하는 과정이다.

import plotly.express as px
from dash import Dash, dcc, html, Input, Output

import pandas as pd

app = Dash(__name__)

# preprocess
data = pd.read_csv("./data/서울시 공동주택 아파트 정보.csv", encoding="cp949")
data = data.loc[:, [
    "k-아파트명", "k-단지분류(아파트,주상복합등등)", "주소(시군구)", "주소(읍면동)", 
    "k-복도유형", "k-난방방식", "k-전체세대수", "주차대수", "좌표X", "좌표Y"]]
data.columns = ["아파트명", "단지분류", "시군구", "읍면동", "복도유형", "난방방식", "세대수", "주차대수", "좌표X", "좌표Y"]
groups = data["시군구"].unique()

# 레이아웃 정의
app.layout = html.Div(children=[
    html.H1(
        children="서울시 공동주택 아파트 정보",
        style={"textAlign": "center"}
    ),
    html.H4(
        children="시군구를 선택하세요", 
    ),
    dcc.Dropdown(
    	id="group",
        options=groups,
        value=groups[0]
    ),
    dcc.Graph(
        id="graph",
    ),
], style={"width": "90%", "margin": "auto"})

# 콜백 정의
@app.callback(
    Output(component_id="graph", component_property="figure"),
    Input(component_id="group", component_property="value"),
)
def update_graph(group):

    # 사용자가 선택한 시군구가 포함된 데이터를 필터링
    selected_data = data.loc[data["시군구"] == group]
    
    # boxplot 그래프 생성
    fig = px.box(
        selected_data, x="시군구", y="세대수"
    )
    return fig

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

 

dash는 입력과 출력에 대한 함수를 @app.callback 이라는 파이썬 데코레이터로 감싸는 구조로 콜백을 구현한다. 여기서 input은  "group"이라는 id를 가진 dropdown 요소이며, output은 "graph"라는 id를 가진 Graph 이다.

 

component_id는 레이아웃에서 입력 또는 출력으로 쓰일 요소의 id를, component_property는 입력 또는 출력으로 쓰일 요소의 파라미터명을 작성한다. 이전 레이아웃만 구성했을 때는 `dcc.Graph(id="graph", figure=fig)` 로, 이미 정의된 figure를 할당했었다. 지금은 사용자의 입력에 따라 graph가 달라지도록 하기 위해 레이아웃을 정의할 때 figure을 할당하지 않고, 콜백의 Output으로 figure를 지정하였다.

 

사용자가 dropdown을 통해 하나의 시군구를 선택하면, dropdown의 value 파라미터가 변경되며 그 값이 함수 update_graph의 입력값으로 들어간다. 해당하는 시군구의 데이터들만 필터링한 후, 그 데이터를 이용해 boxplot을 만들고 figure 파라미터에 전달하고 출력되는 방식이다.

 

 

 

마무리

지금까지 plotly의 Dash를 활용해 웹 어플리케이션을 구현해보았다. 먼저 레이아웃을 구성하고, 콜백을 활용하여 반응형 프로그램을 만들 수 있었다. 누구나 한번 예제를 만들어보면 생각보다 엄청 어렵지 않고 재밌다고 느낄 것 같다. 이번 기회를 통해 dash를 익힐 수 있어 좋았고, 앞으로 다른 프로젝트에서도 사용해보고 싶다 🤗 

 

 

참고

http://bigdata.dongguk.ac.kr/lectures/datascience/_book/a4.-dash%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-python-dashboard.html

 

A4. Dash를 이용한 Python Dashboard | 데이터과학

Dropdown dcc.Dropdown(id, options=[“a”, “b”, “c”], value=[“a”], multi=True, …) 예제보기

bigdata.dongguk.ac.kr

https://asource.tistory.com/31

 

요소와 속성 / 부모요소와 자식요소

요소와 속성 html은 하나의 문서라 볼수 있습니다. 문서는 제목,네비게이션,본문,리스트 등 다양한 요소로 구성되어 있는데, 이를 element(요소)라고 표시합니다. html안에서 요소는 태그로 표시되며

asource.tistory.com

https://towardsdatascience.com/dash-for-beginners-create-interactive-python-dashboards-338bfcb6ffa4

 

Dash for Beginners: Create Interactive Python Dashboards

What is Dash?

towardsdatascience.com