AI를 활용한 재밌는 것들을 개발합니다

2019년 5월 15일 수요일

[ python dash ] 부동산 지역별 평균연령 bar chart 구현

python dash를 공부하면서 메뉴얼 순서대로 공부만 해간다면 재미가 없어 금방 질리게 된다. 이럴때 효과적으로 공부하는 방법은 내가 개발하고 싶은 것을 하나 골라서 매뉴얼을 보면서 구글링을 하면서 구현해 나가면 재미도 있고 성취감도 생겨 학습에 더 도움이 된다.

그래서 구현하려고 하는 것은 행정안전부 웹사이트 -> 주민등록 인구 통계 -> 주민등록 인구 기타현황 -> 그래프 -> 지역별 평균연령 이다. ( http://27.101.213.4/index.jsp# )
부동산에 이제 관심을 가져볼까 하고... 혼자서 부동산 공부도 하는 차에... 부동산과 dash를 동시에 학습할 생각이다.

아래는 python dash로 만든 웹페이지이다. ( geenieland.na.to )

원본은 전체/남자/여자 이렇게 3가지 구분으로 연령 평균을 볼 수 있지만 난 그냥 전체평균으로만 일단 구현해 보았다.

이제 개발 순서를 대략적으로 알아보자.

1. 원 소스 획득 ( 행정안전부 : http://27.101.213.4/index.jsp# )

행정안전부 웹사이트 -> 주민등록 인구 통계 -> 주민등록 인구 기타현황 -> 통계표 -> 지역별 평균연령 -> 최신 날짜 지정 -> 검색 -> 전체읍면동현황 체크 -> csv 파일 다운로드

다운로드 받은 csv 파일을 엑셀로 열어보면 아래와 같다.

평균연령을 [2019년04월_평균연령] 컬럼을 그대로 사용하면 될 것이지만 지역 구분은 [행정구역] 컬럼을 그대로 사용하기는 어렵다.

2. 전처리 : [행정구역] 컬럼 split 나누기

일단 다운로드 받은 csv 파일을 pandas로 읽어 들이고, [행정구역] 컬럼의 문자열을 특정 규칙에 맞게 나누어 주어야 한다.

data = pd.read_csv("201904_201904_주민등록인구기타현황(평균연령)_월간.csv", encoding='euc-kr') 
division = data['행정구역']
division = division.str.replace("("," ")
division = division.str.split(" ",n=10,expand=True )
division = division.drop(columns=[4])

이렇게 하면 아래와 같이 행정구역이 나뉘게 된다.

3. dash : 지역 검색 drop box

위와 같은 UI를 만들어보자.

app.layout = html.Div([
    html.Hr(),
    html.Div(className="row",children=[
        html.Div([
            html.Label('행정구역', style={'vertical-align': 'middle'}),
        ],style={'width': '10%', 'height':'50%', 'display': 'inline-block','textAlign': 'center'}),
        html.Div([
            html.Label('전국', style={'textAlign': 'center'}),
            dcc.Dropdown(
                id='category1',
                options=[{'label': k, 'value': k} for k in division['전국'].unique()],
                value='전국'
            ),
        ],style={'width': '25%', 'display': 'inline-block'}),
        html.Div([
            html.Label('시/군/구', style={'textAlign': 'center'}),
            dcc.Dropdown(
                id='category2',
                options=[{'label': k, 'value': k} for k in division['시/군/구'].unique()],
                value=''
            ),
        ],style={'width': '25%', 'display': 'inline-block'}),
        html.Div([
            html.Label('구', style={'textAlign': 'center'}),
            dcc.Dropdown(
                id='category3',
                options=[{'label': k, 'value': k} for k in division['구/읍/면/동'].unique()],
                value=''
            ),
        ],style={'width': '25%', 'display': 'inline-block'}),
    ],style={'width': '98%', 'display': 'inline-block','vertical-align': 'middle'}), 
])
@app.callback(
    Output('category2', 'options'),
    [Input('category1', 'value')])
def set_category2_options(selected_category1):
    return [{'label': i, 'value': i} for i in division[division['전국']==selected_category1]['시/군/구'].unique()]

@app.callback(
    Output('category3', 'options'),
    [Input('category1', 'value'),
    Input('category2', 'value')])
def set_category2_options(selected_category1,selected_category2):
    return [{'label': i, 'value': i} for i in division[(division['전국']==selected_category1) & 
                                                    (division['시/군/구']==selected_category2)]['구/읍/면/동'].unique()]
 
4. dash : bar chart

@app.callback(
    Output('NewestGraph', 'figure'),
    [Input('category1', 'value'),
     Input('category2', 'value'),
     Input('category3', 'value')])
def update_NewestGraph(selected_category1, selected_category2, selected_category3):
    return {
        'data': [go.Bar(
            x=final_graph['읍/면/동'],
            y=final_graph['2019년04월_평균연령'],
            text=final_graph['2019년04월_평균연령'],
            textposition = 'auto',
            opacity=0.6,
            marker=dict(
                color='rgb(158,202,225)',
                line=dict(
                    color='rgb(8,48,107)',
                    width=1.5),
            ),
            
        )],
        'layout': go.Layout(
            xaxis={                            
            },
            yaxis=dict(
                title = '평균연령',               
                range = [25,70]
            ),
            margin={'l': 40, 'b': 150, 't': 10, 'r': 40},
            hovermode='closest'
        )
    }

끝.

댓글 1개:

  1. 안녕하세요. 포스팅 감사합니다. 따라서 코드를 작성했는데 dcc.Graph 부분이 없어서 그래프가 그려지지 않네요. 공유 부탁드립니다. 감사합니다.

    답글삭제

가장 많이 본 글