차밍이

Plotly를 사용한 파이썬 시각화 using 코로나 데이터셋 본문

파이썬/데이터 시각화

Plotly를 사용한 파이썬 시각화 using 코로나 데이터셋

2020. 4. 29. 22:26
반응형

안녕하세요. 오늘은 plotly를 사용해서 데이터 시각화 및 EDA를 진행했던 내용을 포스팅하려고 합니다.

plotly는 쉽게 사용할 수 있으면서도 matplotlib보다 더 예쁘고 인터랙티브 한 자료를 만들 수 있어서 유용합니다.

본 글을 통해서 plotly를 더 활용하실 수 있으면 좋겠습니다.

 

사용한 데이터

Kaggle에 업로드된 코로나 데이터 셋을 사용했습니다. 본 데이터는 DS4C가 질병관리본부 데이터를 수집 및 가공해서 업로드한 것으로 알고 있습니다. 데이터셋 다운 링크는 아래를 참고해주세요.

오늘 사용한 EDA는 시간에 따른 시각화입니다. 그래서 다양한 데이터들 중에서 Time과 관련된 데이터만을 사용했습니다.

https://www.kaggle.com/kimjihoo/coronavirusdataset

 

Data Science for COVID-19 (DS4C)

DS4C: Data Science for COVID-19 in South Korea

www.kaggle.com

 

Plotly & EDA 소스코드

기본 설정

# essential libraries
import os
import numpy as np
import pandas as pd

import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# for offline ploting
from plotly.offline import plot, iplot, init_notebook_mode
init_notebook_mode(connected=True)
import plotly.io as pio
pio.renderers.default = "notebook_connected"

# 데이터셋
time = pd.read_csv('Time.csv')
timeAge = pd.read_csv('timeAge.csv')
timeGender = pd.read_csv('timeGender.csv')
timeProvince = pd.read_csv('TimeProvince.csv',)

# color pallette
cnf, dth, rec, act = '#393e46', '#ff2e63', '#21bf73', '#fe9801' 
DEFAULT_PLOTLY_COLORS=['rgb(31, 119, 180)', 'rgb(255, 127, 14)',
                       'rgb(44, 160, 44)', 'rgb(214, 39, 40)',
                       'rgb(148, 103, 189)', 'rgb(140, 86, 75)',
                       'rgb(227, 119, 194)', 'rgb(127, 127, 127)',
                       'rgb(188, 189, 34)', 'rgb(23, 190, 207)']

# 기본 폰트 설정
layout_font = {'font':dict(size=18,color='#60606e',family='Franklin Gothic' )}

 

Scatter Plot : 여러 그래프 겹쳐 그리기

일반적인 Scatter plot과는 조금 거리가 먼 line plot에 가까운 사용 방식입니다.

fig = go.Figure()
fig.add_trace(go.Scatter(x=time['date'],y=time['released'],
             mode='lines+markers', name='released'))
fig.add_trace(go.Scatter(x=time['date'],y=time['confirmed'],
             mode='lines+markers', name='confirmed'))
fig.add_trace(go.Scatter(x=time['date'],y=time['deceased'],
             mode='lines+markers', name='deceased'))

fig.update_layout(title='<b>시간에 따른 확진자 추이</b>', **layout_setting)
fig.show()

 

Scatter Plot : 여러 그래프 겹쳐 그리기

fig = make_subplots(rows=1, cols=1, shared_xaxes=True)
fig.add_trace(go.Scatter(x=time['date'],y=time['negative'],
             mode='lines+markers', name='Negative'))
fig.add_trace(go.Scatter(x=time['date'],y=time['test'],
             mode='lines+markers', name='Test'))

fig.update_layout(title='<b>검사자 수와 음성판정자 수</b>', **layout_setting)
fig.show()

 

Bar 그래프 : 그래프 색깔 지정

fig = go.Figure()
fig.add_trace(go.Bar(x=time['date'],y=time['confirmed'].diff(), 
                     name='confirmed', marker_color='rgba(152, 0, 0, .8)'))

fig.update_layout(title='<b>일단위 확진자 수</b>')

fig.show()

 

Bar 그래프 : 특정 부분만 색깔 주기

일반적으로 색깔 하나를 지정하거나 연속형 color set을 사용하면 됩니다. 조금 번거롭지만 BAR 그래프에서 특정 몇 개의 bar에만 색깔을 지정해줄 수 있습니다.

직접 바에 색깔을 주려면 bar의 개수만큼의 color list가 필요합니다.

아래 소스코드의 clr 부분을 보면 특정 날짜 범위에 해당되면 `기본 컬러 3번`을 사용하고 그외의 경우는 `기본컬러 7번`을 사용하는 list comprehention을 통해 색깔 리스트를 만들었습니다. 이후 marker에서 color에 설정을 넣어주면서 2월 17일부터 3월 5일까지의 데이터에 대해서는 빨간색을 나타내도록 하였습니다.

time['date'] = pd.to_datetime(time['date'])
start = dt.strptime('2020-02-17', '%Y-%m-%d')
mid = dt.strptime('2020-03-05', '%Y-%m-%d')

fig = go.Figure()
clr = [DEFAULT_PLOTLY_COLORS[3] if start <= d <= mid else DEFAULT_PLOTLY_COLORS[7] for d in time['date']]
fig.add_trace(go.Bar(x=time['date'],y=time['confirmed'].diff(), 
                     name='confirmed', marker=dict(color=clr)))

fig.update_layout(title='<b>일단위 확진자 수</b>',**layout_setting)

fig.show()

 

Stacked Bar 그래프 : 누적에 색깔별로 구분을 주기

fig = px.bar(timeAge, x='date', y='confirmed',
             hover_data=['age'], color='age', )

fig.update_layout(title='<b>연령별 확진자 추이</b>', **layout_setting)
fig.show()

 

Scatter Plot + Line Plot

timeAge_Date = timeAge.pivot_table(index = ['date'],columns=['age'], aggfunc=sum)
timeAge_Date['deceased']

fig = go.Figure()
for col in timeAge_Date['deceased'].columns:
    fig.add_trace(go.Scatter(x=timeAge_Date.index,y= timeAge_Date['deceased'][col],
                 mode='lines+markers', name=col))
# ... #
fig.update_layout(title='<b>연령별 사망자 추이</b>', **layout_setting)
fig.show()

 

Plotly : Subplot 적용하는 법

Gender_Date = timeGender.pivot_table(index = ['date'],columns=['sex'], aggfunc=sum)
Gender_Confirmed = Gender_Date['confirmed']
Gender_Deceased = Gender_Date['deceased']

fig = make_subplots(rows=1, cols=2,
                    horizontal_spacing= 0.15,
                   subplot_titles=('<b>남여 확진자 수</b>','<b>남여 사망자 수</b>'))

fig.add_trace(go.Scatter(x=Gender_Confirmed.index, y=Gender_Confirmed['male'],
                 mode='lines', name="Male", line=dict(color='#3370ff')), row=1, col=1)
fig.add_trace(go.Scatter(x=Gender_Confirmed.index, y=Gender_Confirmed['female'],
                 mode='lines', name="Female", line=dict(color='#ff0d5f')), row=1, col=1)

fig.add_trace(go.Scatter(x=Gender_Deceased.index, y=Gender_Deceased['male'],
                 mode='lines', name="Male", showlegend=False, line=dict(color='#3370ff')), row=1, col=2)
fig.add_trace(go.Scatter(x=Gender_Deceased.index, y=Gender_Deceased['female'],
                 mode='lines', name="Female", showlegend=False, line=dict(color='#ff0d5f')), row=1, col=2)

fig.update_layout(title='<b>성별 확진자 및 사망자 수</b>', font = layout_setting['font'], showlegend=True)

fig.update_xaxes(title_text="Month", row=1, col=1)
fig.update_xaxes(title_text="Month", row=1, col=2)
fig.update_yaxes(title_text="Number", row=1, col=1)
fig.update_yaxes(title_text="Number", row=1, col=2)

for i in fig['layout']['annotations']:
    i['font'] = dict(size=18)

fig.show()

Subplot 별로 x축 y축의 라벨을 만들 수 있습니다.

 

subplot 만들기

Province_Date = timeProvince.pivot_table(index='date',columns='province')
top = Province_Date['confirmed'].sum().sort_values(ascending=False)[:5]

fig = make_subplots(rows=2, cols=1, subplot_titles=('<b>지역별 확진자 추이</b>','<b>지역별 사망자 추이</b>'))

for i, col in enumerate(list(top.index)):
    fig.add_trace(go.Scatter(x=Province_Date.index[20:],
                             y= Province_Date['confirmed'].iloc[20:,:][col],
                             mode='lines', name=col,
                            line=dict(color=DEFAULT_PLOTLY_COLORS[i], width=2)),row=1, col=1)

for i, col in enumerate(list(top.index)):
    fig.add_trace(go.Scatter(x=Province_Date.index[20:],
                             y= Province_Date['deceased'].iloc[20:,:][col],
                             mode='lines', name=col, showlegend=False,
                             line=dict(color=DEFAULT_PLOTLY_COLORS[i], width=2)), row=2, col=1)


fig.update_xaxes(title_text="Month", row=1, col=1)
fig.update_xaxes(title_text="Month", row=2, col=1)
fig.update_yaxes(title_text="Number", row=1, col=1)
fig.update_yaxes(title_text="Number", row=2, col=1)

fig.update_layout(title='<b>확진자 상위 7개 지역의 추이</b>', height=800,
                  font=dict(size=18,color='#60606e',family='Franklin Gothic'))
for i in fig['layout']['annotations']:
    i['font'] = dict(size=18)
fig.show()

 

Subplot 만들기 + legend위치 지정

다행 다열로 subplot을 만드는 방법입니다.

table = Province_Date
provinces = timeProvince['province'].unique()
isolated = pd.DataFrame(table['confirmed'] - table['deceased'] - table['released'])

fig = make_subplots(rows=6, cols=3, horizontal_spacing=0.03,
                    vertical_spacing= 0.05,
                   subplot_titles=([f'<b>{prov}</b>' for prov in provinces]))

for i, province in enumerate(provinces):
    row, col, legend = i//3 + 1, i%3 + 1, False
    if i == len(provinces)-1 :
        legend = True
    fig.add_trace(go.Scatter(x=table.index, y=table['confirmed'][province],
                     mode='lines', name="Confirmed", 
                     marker=dict(color = DEFAULT_PLOTLY_COLORS[3]), showlegend=legend), row=row, col=col)
    fig.add_trace(go.Scatter(x=table.index, y=table['deceased'][province],
                     mode='lines', name="Deceased", 
                     marker=dict(color = DEFAULT_PLOTLY_COLORS[2]), showlegend=legend), row=row, col=col)
    fig.add_trace(go.Scatter(x=table.index, y=table['released'][province],
                     mode='lines', name="Released",
                     marker=dict(color = DEFAULT_PLOTLY_COLORS[9]), showlegend=legend), row=row, col=col)
    fig.add_trace(go.Scatter(x=table.index, y=isolated[province],
                     mode='lines', name="Isolated",
                     marker=dict(color = DEFAULT_PLOTLY_COLORS[1]), showlegend=legend), row=row, col=col)

fig.update_layout(title='<b>지역별 환자 추이</b>',
                  height = 2000, font = layout_setting['font'],
                  legend=dict(x=0.7, y=0.05, traceorder="normal",
                             font=dict(family="sans-serif", size=18)))
for i in fig['layout']['annotations']:
    i['font'] = dict(size=20)

fig.show()

지금까지 Plotly를 사용한 시각화를 코로나 데이터셋을 사용해서 진행해보았습니다.

plotly를 사용하는 방법에 참고가 되었다면 좋겠습니다.

추가적으로 DACON에서 진행하는 코로나 시각화 경진대회에 작성한 글을 참고하시면 더 많은 내용이 추가될 수 있을 것입니다. 그리고 저희 팀이 작성한 글도 한번 읽어보시고 추천 눌러주시면 감사하겠습니다!! ㅎ

EDA 및 시각화 글

https://dacon.io/competitions/official/235590/codeshare/1032?page=1&dtype=recent

 

월간 데이콘 4 코로나 데이터 시각화 경진대회

출처 : DACON - Data Science Competition

dacon.io

 

분석글

https://dacon.io/competitions/official/235590/codeshare/1001

 

월간 데이콘 4 코로나 데이터 시각화 경진대회

출처 : DACON - Data Science Competition

dacon.io

반응형

관련된 글 보기

Comments