plotly로 시각화 뽀개기

choonsikmom·2022년 8월 31일
0

데이터분석의 꽃은 역시 시각화🥰

공식문서를 참조해서 plotly로 다양하고 예쁜(?) 시각화를 해보자!

plotly의 가장 큰 장점은 차트와 인터랙션이 가능하다는 점이고, matplotlib에 비해 더 예쁘다!


[공식문서 링크] plotly python open sources

plotly의 공식문서인데 오픈소스 정리가 잘 되어있어서 사용하기 편리하다 :)

정리가 잘 되어있는데 왜 벨로그에 따로 정리를 하느냐???

그건 plotly의 다양한 옵션들을 같이 활용하고(레이아웃 설정, 타이틀 설정 등), 이 옵션들의 활용법을 잘 정리해서 다시 쓰기 유용하기 하기 위함이다! 🤗

그리고 plotly를 그리는 방법에는 plotly.express를 활용한 방법과 plotly.graph_objects를 활용한 방법 크게 2가지가 있는데, 요 방법에 따라 값 방식이 달라서 헷갈리는 때가 많기 때문에... 잘 정리해 두면 좋을거 같기도 하고 !!


1. bar plot


▪ barchart (horizontal)

plotly에 샘플 데이터로 주어진 gapminder를 사용하여 바차트 시각화를 해보자.

import plotly.express as px

df = px.data.gapminder()

fig = px.bar(df.sort_values('year', ascending=False).head(10),  orientation='h',
             x= 'gdpPercap',
             y='country',
             color='country',text ='gdpPercap',
             barmode='stack')
fig.update_layout( legend={'title': None})
fig.update_xaxes(title=None)
fig.update_yaxes(title=None)
title={'text': "gdpPercap Top 10 Countries",
        'y':0.95,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'}
fig.update_traces(texttemplate='%{text:.3s}', textposition="outside")

fig.update_layout(
                title=title)
fig.show()

px.bar()를 활용해서 그릴 때는, 데이터(df)를 지정해 넣고 x, y 옵션에 해당 데이터의 컬럼 값을 주면 된다.
이 샘플 코드에서는 x값이 gdpPercap으로 숫자 밸류, y값이 country로 문자 라벨 값으로 구성된다.

또한 color 값은 지정한 컬럼에 따라 컬러를 다르게 주겠다는 의미이며(여기서는 라벨에 따라 다른 색상),
특정 값을 텍스트로 따로 표기하고 싶다면 text 옵션에 표기하고자 하는 컬럼값을 넣어주면 된다.

horizontal으로 barchart를 그리기 위해서는, orientation에 'h' 옵션을 주고 x값과 y값을 반대로 주면 된다.
(y값을 라벨로 x값을 밸류로 -> y값을 라벨로 x값을 밸류로 전환!)

디폴트 옵션은 'v' 로, vertical을 그릴 때는 생략해도 되는 옵션이다.

plotly에서 타이틀 가운데 정렬이 없어서 아쉬운데, 위의 설정에서 텍스트 길이나 그래프에 따라 약간씩 x, y값을 조정하면 얼추 맞는다. 타이틀 옵션을 미리 설정해 두고, fig.update_layout()에서 설정한 값들을 넣어주면 편하다.

fig.update_traces()에서 px.bar에서 설정한 텍스트의 템플릿을 변경할 수 있다. 여기서는 출력 형식을 {:.3s} 로 지정해 주었다.


▪ barchart group vertical + line plot


import plotly.graph_objects as go
continents = ['Asia', 'Europe', 'Africa', 'Americas', 'Oceania']

# barplot
fig = go.Figure(data =[
    go.Bar(name = '1960', x=continents, 
    y=df[df['year']==1962]['gdpPercap'].sort_values(ascending=False).head(),
    marker_color='#6ee274'),
    go.Bar(name = '1992', x=continents, 
    y=df[df['year']==1992]['gdpPercap'].sort_values(ascending=False).head(),
    marker_color='#fca4a1'),
      
])

# lineplot
fig.add_scatter(x=continents, y=[df[df['continent']=='Asia']['gdpPercap'].mean(),
                                df[df['continent']=='Europe']['gdpPercap'].mean(),
                                df[df['continent']=='Africa']['gdpPercap'].mean(),
                                df[df['continent']=='Americas']['gdpPercap'].mean(),
                                 df[df['continent']=='Oceania']['gdpPercap'].mean()
                                ],
               name='mean', line=dict(color='#C00000'))

fig.update_layout(barmode='group')
fig.show()

다음은 go.Bar()를 이용해서 바차트를 그려보자. 한개만 그리면 밋밋하니까(?) 라인플롯도 겸해보았다.
보통 1개 이상의 차트를 한 피규어 내에 그릴 때에는 go를 많이 사용하는 것 같다.

go.Bar()를 2가지 넣어서 1960년과 1992년의 gdpPercap 수치를 비교해 보는 그래프이다.
group형 barchart를 그리기 위해서는 update_layout에서 barmode를 group으로 지정하면 된다.

plotly에서는 scatterplot으로 lineplot을 표현할 수 있는데, line에 옵션 여러가지를 dict로 만들어 전달하면 된다. (color, width=4, dash 등 여러 옵션이 있다.)
이를 이용해서 각 continent의 gdpPercap 평균 수치를 나타내 보았다.


▪ barchart vertical + stacked

df = px.data.gapminder()

fig = px.bar(df[(df['year'].isin([1952, 1962, 1972, 1982, 1992, 2002])) & 
                df['country'].isin(['China', 'Japan', 'Korea, Rep.'])]
             , x='country', y='gdpPercap', color='year')
fig.show()

다음은 중국, 일본, 한국 국가별 gdpPercap을 연도별로 구분해서 그린 바차트이다. 연도 구분을 색상으로 표현해서 y값 위에 쌓고 있다.
(위에서 설명한것과 거의 중복이여서 코드 설명은 생략)


▪ barchart vertical + animate

import plotly.express as px

df = px.data.gapminder()

fig = px.bar(df, x="continent", y="pop", color="continent",
  animation_frame="year", animation_group="country", range_y=[0,4000000000])
fig.show()


2. pie plot


▪ single pie chart

import plotly.graph_objects as go

fig = go.Figure(data=[go.Pie(labels=labels, 
                            values=values,
                            textinfo='label+percent')])

fig.show()


▪ dual pie chart

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

fig = make_subplots(1, 2, 
                    specs=[[{'type':'domain'}, {'type':'domain'}]],
                    subplot_titles=['Asia' , 'Europe'])

labels = df[(df['continent']=='Asia')&
	(df['year']==2007)].sort_values('gdpPercap',ascending=False).head(5)['country'].values
values = df[(df['continent']=='Asia')&
	(df['year']==2007)].sort_values('gdpPercap',ascending=False).head(5)['gdpPercap'].values

fig.add_trace(go.Pie(labels=labels, values=values), 1, 1)


labels = df[(df['continent']=='Europe')&
	(df['year']==2007)].sort_values('gdpPercap',ascending=False).head(5)['country'].values
values = df[(df['continent']=='Europe')&
	(df['year']==2007)].sort_values('gdpPercap',ascending=False).head(5)['gdpPercap'].values

fig.add_trace(go.Pie(labels=labels, values=values), 1, 2)

fig.update_traces(textinfo='label+percent')
fig.show()


▪ dual donut chart

from plotly.subplots import make_subplots
asia_con = df[(df['continent']=='Asia')&
(df['year']==2007)].sort_values('gdpPercap',ascending=False).head(5)['country'].values
europe_con = df[(df['continent']=='Europe')&
(df['year']==2007)].sort_values('gdpPercap',ascending=False).head(5)['country'].values
colors = ['#fd5e53', '#fb9426', '#fef775', '#86f929',  '#29f9c5', '#0c80fc']


# Create subplots: use 'domain' type for Pie subplot
fig = make_subplots(rows=1, cols=2, specs=[[{'type':'domain'}, {'type':'domain'}]])
fig.add_trace(go.Pie(labels=asia_con, values=df[(df['continent']=='Asia')&
(df['year']==2007)].sort_values('gdpPercap',ascending=False).head(5)['gdpPercap'].values, name="Asia"),
              1, 1)
fig.add_trace(go.Pie(labels=europe_con, values=df[(df['continent']=='Europe')&
(df['year']==2007)].sort_values('gdpPercap',ascending=False).head(5)['gdpPercap'].values, name="Europe"),
              1, 2)

# Use `hole` to create a donut-like pie chart
fig.update_traces(hole=.4, hoverinfo="label+percent+name", 
    marker=dict(colors=colors))

fig.update_layout(
    title_text="2007 Asia & Europe gdpPercap top 5",
    # Add annotations in the center of the donut pies.
    annotations=[dict(text='Asia Top 5', x=0.16, y=0.5, font_size=17, showarrow=False),
                 dict(text='Europe Top 5', x=0.86, y=0.5, font_size=17, showarrow=False)])
fig.show()


3. line plot


fig = px.line(df[df['continent']=='Europe'], y='gdpPercap', 
              x='year', color='country', markers=True)
fig.show()

4. dist plot


▪ histogram

fig = px.histogram(df, x='gdpPercap', color='continent')
fig.show()

px.histogram()을 활용하여 히스토그램을 그리는 코드이다.
color에 따라 여러 continent의 gdpPercap 값 분포를 한 피규어에 그릴 수 있다.

fig = make_subplots(rows=1, cols=2,
                   subplot_titles=['1957 pop', '2007 pop'])


t1 = go.Histogram(x=df[df['year']==1957]['pop'], name='1957')

t2 = go.Histogram(x=df[df['year']==2007]['pop'], name='2007')

fig.append_trace(t1, 1, 1)
fig.append_trace(t2, 1, 2)

fig.show()

2개의 피규어에 subplot으로 따로 그리고 싶다면 위와 같이 make_subplots로 옵션을 주고
2개의 히스토그램을 그려 넣으면 된다.


▪ horizontal box plot

fig = go.Figure()
fig.add_trace(go.Box(x=df[df['year']<=1970]['gdpPercap'], name='~1970'))
fig.add_trace(go.Box(x=df[df['year']>1970]['gdpPercap'], name='1970~'))

fig.show()

다음은 1970년까지의 gdp와 이후의 gdp 분포를 나타낸 박스플롯이다.

y값 대신 x값을 설정하면 horizontal box plot을 그릴 수 있고, add_trace()를 통해 2개의 박스플롯을 한 피규어 내에 그릴 수 있다.


▪ violin plot

fig = go.Figure()

label = ['~1970', '1970~']

fig.add_trace(go.Violin(y=df[df['year']<=1970]['gdpPercap'].values,
                       name=label[0],
                        box_visible=True,
                       meanline_visible=True)
             )
fig.add_trace(go.Violin(y=df[df['year']>1970]['gdpPercap'].values,
                       name=label[1],
                        box_visible=True,
                       meanline_visible=True)
             )
fig.show()

boxplot과 동일한 데이터를 바이올린 플롯으로 표현해보자.

크게 달라질 건 없는데, box_visible 옵션과 meanline_visible 옵션이 추가되어 있다.
box_visible은 바이올린 플롯 안에 박스 표시 여부이고, meanline은 평균값을 추가로 표시할 수 있다.


▪ violin plot with points

fig = px.violin(df[(df['country']=='Japan') | (df['country']=='Portugal') | 
                   (df['country']=='Belgium') |  (df['country']=='France') |
                  (df['country']=='Korea, Rep.')], 
                y='gdpPercap', x='continent', color='country', points='all',
         hover_data=df.columns)

fig.show()

point 옵션을 설정하면 밸류들을 바이올린 플롯 옆에 점으로 표시해준다.


5. plotly map



fig = px.scatter_mapbox(
                        kyeungkido, 
                        lat=kyeungkido.y, 
                        lon=kyeungkido.x, 
                        size='area', 
                        color='area', 
                        hover_name = 'area',
    center=dict(lat=37.26, lon=127.02),
                  color_continuous_scale=px.colors.colorbrewer.RdYlGn,  
                        size_max=30, 
                        zoom=8  , mapbox_style="carto-positron"
                    )
                    
fig.show()                  

plotly로도 folium과 같은 map을 그릴 수 있는데, 위 그래프는 scatter를 map에 표현한 것이다.


정리한 것 외에도 그래프 그리는 방식은 무궁무진하고, plotly에서는 dash를 지원해주니
다양한 방법으로 시각화를 즐겨보자구요 😊😉

profile
춘식이랑 함께하는 개발일지.. 그런데 이제 먼작귀를 곁들인

0개의 댓글