Python 시각화 - newlife-js/Wiki GitHub Wiki

Matplotlib

파이썬 시각화의 기본(matplotlib.org)

import matplotlib.pyplot as plt
※ 스타일
plt.plot(x, y, 'ko--')
plt.plot(x, y, color='k', linestyle='dashed', marker='o'

k: 검정색(약자를 사용해도 되고, RGB 코드 사용해도 됨), o: 원모양, --: 점선

color

marker

line

label, title, legend


■ figure: 그림이 그려지는 캔버스(matplotlib의 기본 컨테이너)

모든 그림은 Figure 객체임
일반적으로 plot명령 등을 실행하면 자동으로 Figure를 생성함

fig = plt.Figure(figsize=(10,5))

■ axes: 하나의 플롯

# plt.subplot(행,열,index)
plt.subplot(211) # plt.subplot(2,1,1)
plt.plot()
plt.subplot(212)
plt.plot()
fig=plt.figure()
ax1=fig.add_subplot(2,1,1)
ax1.plot()
ax2 = fig.add_subplot(2,1,2)
ax2.plot()

plt.tight_layout() # subplot끼리 겹치지 않도록

예) 3번째 플랏은 figure를 2개로 나눈거의 2번째라는 뜻임(1번째는 그리지 않은 것)

■ axis: 그래프의 x축, y축에 대한 눈금(tick)과 label을 가짐
■ spines: 데이터 영역 경계를 나타내는 선
■ 저장: plt.savefig('figpath.png', dpi=400, bbox_inched='tight')

  • dpi: 해상도
  • bbox_inches: 저장할 그래프의 영역

OO-style(객체지향 스타일)

figure와 axes 객체를 명시적으로 선언해준 후에 플랏

fig, ax = plt.subplots()

■ axis limit
equal: x축과 y축의 scale을 동일하게 맞춤

■ rcParams 설정
matplotlib의 rc 설정은 matplotlib.rc 라고 불리는 dictionary-like 변수에 저장되어 있다.

import matplotlib as mpl
mpl.rcParams['lines.linewidth'] = 2
mpl.rcParams['lines.linestyle'] = '--'

■ 텍스트
matplotlib은 LaTex 표현식 허용

■ Annotate: 주석 달기


Seaborn

Matplotlib 기반으로 다양한 색상 테마와 통계용 차트 등의 기능을 추가(seaborn.pydata.org)
통계 기능은 Statsmodels 패키지에 의존
Matplotlib에 비해 쉽고 직관적, 시각화 결과가 훨씬 보기 좋음
pandas와 궁합이 좋아서 dataframe의 입력을 받아 그릴 수 있음
시각화에 필요한 통계량 계산을 내부적으로 처리
sample 데이터셋을 제공(sns.load_dataset())

■ Figure level plot

■ Wide format 지원


※ Pandas

pandas plot doc
DataFrame을 직접 사용하여 시각화를 할 수 있음
plot이라는 메소드를 사용, matplotlib을 내부에서 임포트하고 있음
plot메소드의 kind 인수로 다양한 종류의 플롯을 하거나, df.plot.bar()와 같이 직접 메소드 사용 가능

dataframe style 참고
예)


Plotly

Plotly Javascript library 기반 interactive 플랏 라이브러리(plotly.com) 복잡한 플로팅 옵션(zoom, 저장등), hovering 기능 제공

장점: 코드의 간편함, interactivity, Dashboard 작성이 용이

  • graph_object: 저수준 api를 통해 일일이 지정해서 그림(그래프 커스터마이징에 이점)
  • express: 다양한 유형의 데이터에서 작동, 스타일 지정이 쉬운 그림 생성, graph_object 위에 구축, 가장 권장하는 방식
  • figure_factory: express 이전에 특정 유형의 플롯을 쉽게 생성해주는 모듈(지금은 잘 사용하지 않음)

예 1) express

import plotly.express as px
fig = px.bar(df, x="Fruit", y="Number Eaten", color="Contestant", barmode="group")

예 2) graph_object

import plotly.graph_objects as go
fig = go.Figure()
for contestant, group in df.groupby("Contestant"):
    fig.add_trace(go.Bar(x=group["Fruit"], y=group["Number Eaten"], name=contestant,
      hovertemplate="Contestant=%s<br>Fruit=%%{x}<br>Number Eaten=%%{y}<extra></extra>"% contestant))
fig.update_layout(legend_title_text = "Contestant")
fig.update_xaxes(title_text="Fruit")
fig.update_yaxes(title_text="Number Eaten")
  • add_trace: figure에 차트 추가
  • update_layout: 레이아웃의 속성 변경
  • update_traces: 여러 trace의 속성 변경
# update_traces 를 통해서 막대그래프의 색깔을 모두 변경한다.
fig.update_traces(marker=dict(color="RoyalBlue"),
                  selector=dict(type="bar"))
  • for_each_trace: 각 trace에 조건별로 속성 변경
fig.for_each_trace(
    lambda trace: trace.update(marker_symbol="square") if trace.name == "setosa" else (),
)

■ subplot

from plotly.subplots import make_subplots

fig = make_subplots(rows=1, cols=2)
fig.add_trace(go.Scatter(y=[4, 2, 1], mode="lines"), row=1, col=1)
fig.add_trace(go.Bar(y=[2, 1, 3]), row=1, col=2)

※ pandas로도 plotly 그릴 수 있음 plotly docs

pd.options.plotting.backend = "plotly"

df = pd.DataFrame(dict(a=[1,3,2], b=[3,2,1]))
fig = df.plot(title="Pandas Backend Example", template="simple_white",
              labels=dict(index="time", value="money", variable="option"))
fig.update_yaxes(tickprefix="$")

수량 데이터 시각화

countplot: 범주별 빈도수

barplot: 범주별 합계

※ ci: 신뢰구간(error bar 표시)

catplot(figure-level categorical plot)

pointplot: 막대의 끝을 점으로, error bar를 선으로 표시


데이터 분포 시각화

histogram

KDE(Kernel Density Estimation)

관측 데이터 각각마다 데이터 값을 중심으로 하는 커널 함수 생성
이렇게 만들어진 커널 함수들을 모두 더한 후 전체 데이터 개수로 나눔
가우시안 커널 함수를 가장 많이 사용

Box plot

각 범주별 연속형 수치 데이터의 분포 특성 비교

IQR에 1.5를 곱하는 이유눈 3시그마 정도(99.xx%)

Violin plot

Box plot에 KDE를 같이 표현한 형태(데이터의 분포를 더 자세히 알 수 있음)


비율 데이터 시각화

파이차트 / 누적 막대 그래프 / 병렬막대그래프 ※ 파이차트는 오히려 비율 비교에 비효율적일 수 있음 -> 병렬막대그래프가 효과적(ex: 연도별 회사 점유율 비교)

Mosaic Plot

다변량 범주형 데이터의 비율을 효과적으로 나타내기 위한 차트

Tree Map

계층구조의 다변량 범주형 데이터 시각화
많은 범주 간의 부분-전체 관계 시각화
Plotly가 편함
image


정량 변수 관계 시각화

산점도

Scatter plot: 상관관계, outlier 확인

※ overplotting: 수치가 똑같은 관측 값이 여러 개가 한 포인트에 찍히는 것
-> 투명도(alpha) 적용, jittering, hexagonal binning, 밀도 등고선 그래프

Strip chart: 범주별 데이터 포인트들을 일일일 점 형태로 찍어서 표시

Swarm plot: strip chart + jittering

image

Sina plot: strip chart/swarm plot + violin plot/box plot

Bubble chart: 산점도에 점의 크기 속성을 이용

Pair plot: 여러 개의 연속형 변수에 대해서 각 쌍을 이루어 산점도를 그림

correlogram/corrgram: 상관계수 행렬을 도표화(heat map, contour map)


※ 시각화시 주의해야할 것들

  • 색약을 위한 색상표(https://remain.co.kr/page/designsystem/color-wraning.php) image

  • 캡션을 넣는다면 도표의 제목은 캡션과 함께 배치하도록 한다

  • 3D 차트는 가독성을 해칠 수 있으니 사용을 자제한다

  • 비율을 나타낼 때는 파이차트보다 막대차트가 가독성이 더 좋다


Dashboard

  • plotly dash: production/enterprise 환경에 중점
  • streamlit 신속한 prototyping 생성에 중점(dash에 비해 기능은 적지만 쉽고 간단)

Plotly Dash

Dash Documnet Flask, Plotly.js, React.js 위에 구축

장점: 커스터마이즈된 사용자 인터페이스를 사용하여 데이터 시각화 앱을 빌드하는 데 이상적

단점: html/css에 대한 학습이 필요

layout(전체적인 디자인)과 callback(interaction)으로 구성됨
■ layout: dash_html_components(html태그와 속성 class 제공), dash_core_components(plotly 그래프, 탭, 슬라이더, 입력 등)
■ callback: 상호작용 제어 함수
@app.callback 데코레이터 사용
Input(or State) 컴포넌트의 값이 변할 때마다 Output 컴포넌트의 children을 업데이트하라고 알려주는 것
callback 함수의 인수는 input과 state의 순서대로 들어가야 함

@app.callback(Output('output-state', 'children'), 
              Input('submit-button-state', 'n_clicks'), 
              State('input-1-state', 'value'), 
              State('input-2-state', 'value')) 
def update_output(n_clicks, input1, input2): 
    return u''' 
    The Button has been pressed {} times, Input 1 is "{}", and Input 2 is "{}" 
    '''.format(n_clicks, input1, input2) 

■ dash_table: datatable 시각화 모듈

app.layout = html.Div([
    html.H3("Display DataTable"),
    dash_table.DataTable(df.to_dict('records'), [{"name": i, "id": i} for i in df.columns],
                         style_table={'overflowX': 'auto', 'overflowY':'auto'}, 
                         page_size=10)
])

image

Streamlit

Streamlit Gallery 파이썬 기반 웹 어플리케이션 개발 오픈소스

장점: 배우기 쉽고, 개발속도 빠름, API 간단

단점: 복잡한 대화형 패턴 만들기 힘듦, 사용자정의 콜백함수 정의할 방법이 없음

예)
@app.py

import streamlit as st
import pandas as pd

st.title('My first app')
st.write("Here's our first attempt at using data to create a table:")
st.write(pd.DataFrame({
    'first column': [1, 2, 3, 4],
    'second column': [10, 20, 30, 40]
}))

실행 streamlit run app.py

■ write: 문자열뿐 아니라, 데이터프레임, figure 객체 손쉽게 write

■ chart element: 다양한 library의 figure 객체 허용

st.line_chart, st.bar_chart: streamlit 기본 차트
st.pyplot(fig), st.plotly_chart(fig) 사용 가능

■ interactive widget: interactive 컴포넌트

st.slider, st.button, st.selectbox, ...

■ Layout: sidebar, columns, expander, container, empty 등 다양한 배치 요소 가능

■ Caching: 화면의 일부만 변경돼도 모든 함수가 리로드되기 때문에, 속도 향상을 위해 캐싱 가능

  • 함수가 호출될 때마다 매개변수나 사용 변수, 본체 등의 변경사항을 확인하여, 변경도지 않으면 실행하지 않고 로컬 캐시에서 결과를 가져옴
@st.cache(persist=True)
def load_data():
    data = pd.read_csv(DATA_URL)
    data['tweet_created'] = pd.to_datetime(data['tweet_created'])
    return data

data = load_data()
⚠️ **GitHub.com Fallback** ⚠️