Python 시각화 - newlife-js/Wiki GitHub Wiki
파이썬 시각화의 기본(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: 원모양, --: 점선







■ 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: 저장할 그래프의 영역
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: 주석 달기
Matplotlib 기반으로 다양한 색상 테마와 통계용 차트 등의 기능을 추가(seaborn.pydata.org)
통계 기능은 Statsmodels 패키지에 의존
Matplotlib에 비해 쉽고 직관적, 시각화 결과가 훨씬 보기 좋음
pandas와 궁합이 좋아서 dataframe의 입력을 받아 그릴 수 있음
시각화에 필요한 통계량 계산을 내부적으로 처리
sample 데이터셋을 제공(sns.load_dataset())
■ Figure level plot
■ Wide format 지원
pandas plot doc
DataFrame을 직접 사용하여 시각화를 할 수 있음
plot이라는 메소드를 사용, matplotlib을 내부에서 임포트하고 있음
plot메소드의 kind 인수로 다양한 종류의 플롯을 하거나, df.plot.bar()와 같이 직접 메소드 사용 가능
Plotly Javascript library 기반 interactive 플랏 라이브러리(plotly.com) 복잡한 플로팅 옵션(zoom, 저장등), hovering 기능 제공
- 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="$")





관측 데이터 각각마다 데이터 값을 중심으로 하는 커널 함수 생성
이렇게 만들어진 커널 함수들을 모두 더한 후 전체 데이터 개수로 나눔
가우시안 커널 함수를 가장 많이 사용
각 범주별 연속형 수치 데이터의 분포 특성 비교
IQR에 1.5를 곱하는 이유눈 3시그마 정도(99.xx%)
Box plot에 KDE를 같이 표현한 형태(데이터의 분포를 더 자세히 알 수 있음)
파이차트 / 누적 막대 그래프 / 병렬막대그래프 ※ 파이차트는 오히려 비율 비교에 비효율적일 수 있음 -> 병렬막대그래프가 효과적(ex: 연도별 회사 점유율 비교)
다변량 범주형 데이터의 비율을 효과적으로 나타내기 위한 차트
계층구조의 다변량 범주형 데이터 시각화
많은 범주 간의 부분-전체 관계 시각화
Plotly가 편함
산점도
※ overplotting: 수치가 똑같은 관측 값이 여러 개가 한 포인트에 찍히는 것
-> 투명도(alpha) 적용, jittering, hexagonal binning, 밀도 등고선 그래프




※ 시각화시 주의해야할 것들
-
색약을 위한 색상표(https://remain.co.kr/page/designsystem/color-wraning.php)
-
캡션을 넣는다면 도표의 제목은 캡션과 함께 배치하도록 한다
-
3D 차트는 가독성을 해칠 수 있으니 사용을 자제한다
-
비율을 나타낼 때는 파이차트보다 막대차트가 가독성이 더 좋다
- plotly dash: production/enterprise 환경에 중점
- streamlit 신속한 prototyping 생성에 중점(dash에 비해 기능은 적지만 쉽고 간단)
Dash Documnet Flask, Plotly.js, React.js 위에 구축
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)
])
Streamlit Gallery 파이썬 기반 웹 어플리케이션 개발 오픈소스
예)
@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()