데이터 분석을 하다 보면 평균, 표준편차, 상관계수처럼 숫자로 요약한 결과만으로는 데이터의 모습을 충분히 파악하기 어려운 경우가 많다.
그래서 분석 초반에는 통계값과 시각화를 함께 확인하는 습관이 중요하다.
이번 글에서는 데이터 시각화가 왜 필요한지부터, Python 그래프를 이해할 때 자주 등장하는 Figure, Axes, Axis의 차이와 Matplotlib, Seaborn을 언제 사용하는지까지 정리해본다.
데이터 시각화는 데이터를 그래프 형태로 표현해서 분포, 패턴, 관계, 이상치를 빠르게 파악하는 방법이다.
예를 들어 쇼핑몰의 사용자 행동 데이터를 분석한다고 해보자.
이런 질문은 숫자 표만 보는 것보다 그래프로 확인했을 때 훨씬 빠르게 답을 찾을 수 있다.
원본 데이터
↓
기술 통계 확인
↓
그래프로 분포와 관계 확인
↓
이상치·패턴 발견
↓
추가 분석 방향 결정
즉, 시각화는 단순히 결과를 예쁘게 보여주는 작업이 아니라 분석 과정 자체의 일부라고 볼 수 있다.
평균이나 분산 같은 통계값이 비슷하다고 해서 데이터의 모양까지 같은 것은 아니다.
예를 들어 두 API의 평균 응답 시간이 모두 200ms라고 하더라도 실제 데이터는 다음처럼 다를 수 있다.
평균만 보면 두 API가 비슷해 보이지만, 시각화하면 분포와 이상치 차이가 바로 드러난다.
그래서 EDA에서는 다음 두 가지를 함께 보는 것이 좋다.
| 확인 방법 | 알 수 있는 것 |
|---|---|
| 기술 통계 | 평균, 중앙값, 분산, 최소·최대값 등 수치 요약 |
| 시각화 | 분포 형태, 이상치, 군집, 관계, 추세 |
숫자는 요약하고, 그래프는 구조를 보여준다고 생각하면 이해하기 쉽다.
그래프를 그릴 때 중요한 것은 화려한 디자인보다 분석 목적에 맞는 그래프를 선택하는 것이다.
| 알고 싶은 내용 | 주로 사용하는 그래프 |
|---|---|
| 값의 변화 추세 | 선 그래프 |
| 범주별 크기 비교 | 막대 그래프 |
| 값의 분포 | 히스토그램 |
| 두 수치형 변수의 관계 | 산점도 |
| 분포와 이상치 비교 | 박스플롯 |
| 여러 변수 간 관계 | pairplot, 상관행렬 |
예를 들어 사용자 수의 일별 변화라면 선 그래프가 자연스럽고, 페이지별 클릭 수 비교라면 막대 그래프가 더 적절하다.
그래프를 만들기 전에 먼저 다음 질문을 해보는 것이 좋다.
"이 그래프를 통해 무엇을 확인하려는가?"
이 질문에 답할 수 있어야 그래프 종류와 옵션도 자연스럽게 결정된다.
Python 시각화를 공부할 때 헷갈리기 쉬운 개념이 Figure, Axes, Axis다.
간단히 구분하면 다음과 같다.
Figure
└── Axes
├── x-axis
└── y-axis
Figure는 그래프 전체가 올라가는 하나의 도화지라고 생각하면 된다.
한 개의 그래프만 포함할 수도 있고, 여러 개의 그래프를 함께 배치할 수도 있다.
import matplotlib.pyplot as plt
fig = plt.figure()
plt.show()
이 코드에서는 그래프를 실제로 그리기 전, 전체 그림 영역인 Figure를 만든다.
Axes는 Figure 내부에서 실제 그래프가 그려지는 영역이다.
하나의 Figure 안에 여러 Axes를 배치할 수 있다.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [10, 15, 13, 20])
plt.show()
여기서 역할은 다음과 같다.
fig → 전체 도화지
ax → 실제 그래프 영역
실제로 제목, 축 이름, 그래프 데이터 등을 설정할 때는 ax를 많이 사용한다.
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [10, 15, 13, 20])
ax.set_title('Daily Active Users')
ax.set_xlabel('Day')
ax.set_ylabel('Users')
plt.show()
Axis는 Axes 내부의 실제 축을 의미한다.
일반적인 2차원 그래프라면 다음 두 축이 있다.
그래서 이름이 비슷하지만 구분해서 기억할 필요가 있다.
| 용어 | 의미 |
|---|---|
| Figure | 그래프 전체 영역 |
| Axes | 실제 그래프가 그려지는 공간 |
| Axis | x축, y축 같은 개별 축 |
데이터 분석에서는 변수 여러 개를 동시에 비교해야 하는 경우가 많다.
이럴 때 plt.subplots()를 사용하면 하나의 Figure에 여러 Axes를 만들 수 있다.
예를 들어 웹 서비스의 방문자 수와 주문 수를 함께 확인해보자.
import matplotlib.pyplot as plt
days = [1, 2, 3, 4, 5, 6, 7]
visitors = [120, 150, 180, 170, 210, 240, 260]
orders = [12, 18, 21, 19, 28, 32, 35]
fig, axes = plt.subplots(2, 1, figsize=(8, 6))
axes[0].plot(days, visitors)
axes[0].set_title('Visitors')
axes[1].plot(days, orders)
axes[1].set_title('Orders')
plt.tight_layout()
plt.show()
여기서 핵심은 axes[0], axes[1]처럼 각각의 그래프 영역을 별도로 제어할 수 있다는 점이다.
그래프를 복잡하게 구성해야 할수록 Figure/Axes 구조를 이해하는 것이 중요해진다.
Python에서 데이터 시각화를 할 때 자주 사용하는 라이브러리는 Matplotlib과 Seaborn이다.
둘은 경쟁 관계라기보다 역할이 조금 다르다.
| 항목 | Matplotlib | Seaborn |
|---|---|---|
| 특징 | 기본적인 Python 시각화 라이브러리 | 통계 시각화에 특화 |
| 제어 범위 | 매우 세밀하게 조정 가능 | 비교적 간단한 코드로 표현 가능 |
| 복잡한 레이아웃 | 유연하게 구성 가능 | 상대적으로 제한적 |
| DataFrame 활용 | 직접 설정할 일이 많음 | Pandas 데이터와 연결이 편리함 |
| 추천 상황 | 세밀한 커스터마이징 | 빠른 EDA, 통계 그래프 |
실무에서는 둘 중 하나만 고집하기보다는 Seaborn으로 그래프를 만들고 Matplotlib으로 세부 옵션을 조정하는 방식도 많이 사용한다.
사용자 행동 데이터를 간단한 막대 그래프로 표현해보자.
import matplotlib.pyplot as plt
pages = ['Home', 'Search', 'Product', 'Cart']
clicks = [420, 310, 540, 180]
fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(pages, clicks)
ax.set_title('Clicks by Page')
ax.set_xlabel('Page')
ax.set_ylabel('Clicks')
plt.show()
Matplotlib은 축 이름, 제목, 크기, 배치 등 그래프의 세부 요소를 직접 제어하기 좋다.
같은 데이터를 DataFrame으로 관리하고 있다면 Seaborn을 활용할 수 있다.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.DataFrame({
'page': ['Home', 'Search', 'Product', 'Cart'],
'clicks': [420, 310, 540, 180]
})
sns.barplot(data=df, x='page', y='clicks')
plt.title('Clicks by Page')
plt.show()
Seaborn은 data, x, y 형태로 DataFrame 컬럼을 바로 지정할 수 있어 데이터 분석 코드와 자연스럽게 연결된다.
두 개의 수치형 변수가 함께 변하는지 보고 싶다면 산점도(Scatter Plot)를 사용할 수 있다.
예를 들어 사용자의 체류시간과 구매금액 관계를 확인해보자.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.DataFrame({
'session_minutes': [2, 4, 6, 8, 10, 12, 14],
'purchase_amount': [0, 10, 8, 25, 22, 40, 55]
})
sns.scatterplot(
data=df,
x='session_minutes',
y='purchase_amount'
)
plt.show()
그래프를 볼 때는 단순히 점이 위로 올라가는지만 보는 것이 아니라 다음을 함께 확인해야 한다.
이런 특징은 상관계수 하나만 확인했을 때 놓칠 수 있다.
변수가 여러 개라면 Seaborn의 pairplot()도 유용하다.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.DataFrame({
'visits': [2, 5, 8, 4, 10, 12],
'clicks': [5, 12, 18, 9, 25, 30],
'orders': [0, 1, 2, 1, 3, 4]
})
sns.pairplot(df)
plt.show()
pairplot()은 여러 변수 조합의 산점도와 각 변수의 분포를 한 번에 볼 수 있어 EDA 초반에 변수 간 관계를 훑어볼 때 편리하다.
다만 변수 개수가 많아지면 그래프 수가 급격히 증가하고 메모리 사용량도 커질 수 있다.
따라서 실제 분석에서는 필요한 변수만 골라 사용하는 것이 좋다.
sns.pairplot(df[['visits', 'clicks', 'orders']])
데이터 시각화를 할 때는 단순히 그래프를 만드는 것에서 끝나지 않는다.
그래프를 통해 다음 질문에 답할 수 있어야 한다.
분포는 어떤가?
↓
이상치는 있는가?
↓
변수끼리 관계가 있는가?
↓
시간이나 범주에 따른 패턴이 있는가?
↓
다음 분석에서 무엇을 확인해야 하는가?
특히 머신러닝이나 통계 분석 전에 시각화를 해두면 다음 작업의 방향을 잡는 데 도움이 된다.
예를 들어,
처럼 다음 분석 단계로 자연스럽게 연결할 수 있다.
프론트엔드나 백엔드 개발에서도 시각화는 생각보다 자주 활용된다.
예를 들어 서비스 운영 데이터를 분석한다고 하면 다음과 같은 지표를 그래프로 만들 수 있다.
API 요청 수
오류율
응답 시간
DAU / MAU
페이지별 클릭 수
구매 전환율
사용자 이탈률
이때 중요한 것은 그래프를 만드는 것 자체가 목적이 아니라, 그래프를 통해 문제를 발견하는 것이다.
예를 들어 API 평균 응답 시간이 200ms라는 숫자만 보면 정상처럼 보일 수 있지만, 시간대별 그래프를 확인했을 때 특정 시간에만 1초 이상 치솟는 패턴이 발견될 수도 있다.
결국 시각화는 데이터 분석뿐만 아니라 서비스 모니터링과 문제 해결을 위한 도구로도 활용할 수 있다.
데이터 분석을 시작할 때 숫자만 먼저 계산하기보다 데이터를 직접 그려보는 과정이 생각보다 중요하다.
특히 Figure, Axes 같은 Matplotlib의 기본 구조를 이해해두면 이후 복잡한 그래프를 만들 때 훨씬 수월해진다.
Seaborn까지 함께 익혀두면 빠르게 데이터의 분포와 관계를 확인할 수 있어 EDA 작업에서도 활용도가 높다.
다음 단계에서는 히스토그램, 박스플롯, 산점도, 막대그래프처럼 자주 사용하는 그래프를 직접 그려보면서 그래프별 목적과 옵션을 익혀보면 좋다.