포스트

[Python 100일 챌린지] Day 68 - 데이터 시각화 실전

[Python 100일 챌린지] Day 68 - 데이터 시각화 실전

다양한 차트로 데이터를 표현해봅시다! 🎨

원 그래프, 히스토그램, 산점도… 목적에 맞는 차트 선택이 중요해요! 실무에서 자주 쓰는 시각화를 배워봅시다! 📊

(35분 완독 ⭐⭐)

🎯 오늘의 학습 목표

📚 사전 지식


🎯 학습 목표 1: 원 그래프와 도넛 차트

1.1 기본 원 그래프

1
2
3
4
5
6
7
8
9
10
11
12
import matplotlib.pyplot as plt

# 한글 폰트 설정
plt.rcParams['font.family'] = 'AppleGothic'
plt.rcParams['axes.unicode_minus'] = False

labels = ['Python', 'Java', 'JavaScript', 'C++', '기타']
sizes = [35, 25, 20, 10, 10]

plt.pie(sizes, labels=labels, autopct='%1.1f%%')
plt.title('프로그래밍 언어 점유율')
plt.show()

1.2 원 그래프 꾸미기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'AppleGothic'

labels = ['Python', 'Java', 'JavaScript', 'C++', '기타']
sizes = [35, 25, 20, 10, 10]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
explode = (0.1, 0, 0, 0, 0)  # Python만 튀어나오게

plt.pie(sizes,
        labels=labels,
        colors=colors,
        explode=explode,
        autopct='%1.1f%%',  # 퍼센트 표시
        shadow=True,        # 그림자
        startangle=90)      # 시작 각도

plt.title('프로그래밍 언어 점유율')
plt.show()

1.3 도넛 차트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'AppleGothic'

labels = ['Python', 'Java', 'JavaScript', '기타']
sizes = [40, 30, 20, 10]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4']

# 도넛 차트 = 원 그래프 + 가운데 원
fig, ax = plt.subplots()
ax.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%')

# 가운데 흰 원 추가
centre_circle = plt.Circle((0, 0), 0.5, fc='white')
ax.add_patch(centre_circle)

# 가운데 텍스트
ax.text(0, 0, '언어\n점유율', ha='center', va='center', fontsize=12)

plt.title('프로그래밍 언어 점유율')
plt.show()

🎯 학습 목표 2: 히스토그램과 산점도

2.1 히스토그램 (분포 확인)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.family'] = 'AppleGothic'

# 정규분포 데이터 생성
np.random.seed(42)
scores = np.random.normal(70, 15, 100)  # 평균 70, 표준편차 15

plt.hist(scores, bins=10, edgecolor='black', alpha=0.7)
plt.title('학생 점수 분포')
plt.xlabel('점수')
plt.ylabel('학생 수')
plt.show()

2.2 히스토그램 비교

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.family'] = 'AppleGothic'

np.random.seed(42)
class_a = np.random.normal(75, 10, 50)
class_b = np.random.normal(70, 15, 50)

plt.hist(class_a, bins=10, alpha=0.5, label='A반')
plt.hist(class_b, bins=10, alpha=0.5, label='B반')

plt.title('반별 점수 분포')
plt.xlabel('점수')
plt.ylabel('학생 수')
plt.legend()
plt.show()

2.3 산점도 (상관관계)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.family'] = 'AppleGothic'

np.random.seed(42)
study_hours = np.random.uniform(1, 10, 50)
scores = study_hours * 8 + np.random.normal(0, 5, 50) + 20

plt.scatter(study_hours, scores, alpha=0.7)
plt.title('공부 시간 vs 점수')
plt.xlabel('공부 시간')
plt.ylabel('점수')

# 추세선 추가
z = np.polyfit(study_hours, scores, 1)
p = np.poly1d(z)
plt.plot(study_hours, p(study_hours), "r--", alpha=0.8, label='추세선')

plt.legend()
plt.show()

2.4 버블 차트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.family'] = 'AppleGothic'

# 데이터
x = [1, 2, 3, 4, 5]
y = [10, 20, 15, 25, 30]
sizes = [100, 200, 150, 300, 250]  # 버블 크기

plt.scatter(x, y, s=sizes, alpha=0.5, c=['red', 'blue', 'green', 'orange', 'purple'])
plt.title('버블 차트')
plt.xlabel('X축')
plt.ylabel('Y축')
plt.show()

🎯 학습 목표 3: Pandas와 함께 시각화

3.1 DataFrame에서 바로 그래프

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'AppleGothic'

df = pd.DataFrame({
    '': ['1월', '2월', '3월', '4월', '5월'],
    '매출': [100, 120, 115, 130, 145],
    '비용': [80, 85, 90, 95, 100]
})

# Pandas로 바로 그리기!
df.plot(x='', y=['매출', '비용'], kind='line')
plt.title('월별 매출/비용')
plt.ylabel('금액(만원)')
plt.show()

3.2 다양한 Pandas 차트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'AppleGothic'

df = pd.DataFrame({
    '제품': ['A', 'B', 'C', 'D'],
    '판매량': [300, 250, 180, 200]
})

# 막대 그래프
df.plot(x='제품', y='판매량', kind='bar', color='skyblue')
plt.title('제품별 판매량')
plt.ylabel('판매량')
plt.show()

# 원 그래프
df.plot(y='판매량', kind='pie', labels=df['제품'], autopct='%1.1f%%')
plt.title('제품별 판매 비율')
plt.ylabel('')
plt.show()

3.3 그룹 데이터 시각화

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'AppleGothic'

df = pd.DataFrame({
    '부서': ['영업', '영업', '개발', '개발', '마케팅', '마케팅'],
    '분기': ['1분기', '2분기', '1분기', '2분기', '1분기', '2분기'],
    '매출': [100, 120, 80, 90, 60, 75]
})

# 피벗 후 시각화
pivot = df.pivot(index='분기', columns='부서', values='매출')
pivot.plot(kind='bar')
plt.title('부서별 분기 매출')
plt.ylabel('매출(만원)')
plt.legend(title='부서')
plt.show()

🎯 학습 목표 4: 차트 선택 가이드

4.1 목적별 차트 선택

graph TD
    A[데이터 유형?] --> B{수치 비교}
    A --> C{추세 분석}
    A --> D{분포 확인}
    A --> E{비율 표현}
    A --> F{관계 분석}

    B --> B1[막대 그래프]
    C --> C1[선 그래프]
    D --> D1[히스토그램]
    E --> E1[원/도넛 차트]
    F --> F1[산점도]

4.2 차트별 사용 예시

차트 용도 예시
선 그래프 시간에 따른 변화 주가, 기온 변화
막대 그래프 항목 간 비교 매출 비교, 인기도
원 그래프 전체 대비 비율 시장 점유율
히스토그램 데이터 분포 점수 분포, 나이 분포
산점도 두 변수 관계 키-몸무게, 공부-성적

4.3 실전 대시보드 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

plt.rcParams['font.family'] = 'AppleGothic'

# 샘플 데이터
np.random.seed(42)
months = ['1월', '2월', '3월', '4월', '5월', '6월']
sales = [120, 135, 128, 145, 160, 175]
costs = [100, 105, 110, 115, 120, 125]
categories = ['전자', '의류', '식품', '기타']
cat_values = [40, 30, 20, 10]
daily_sales = np.random.normal(50, 10, 30)

# 2x2 대시보드
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

# 1. 매출 추이 (선 그래프)
axes[0, 0].plot(months, sales, 'b-o', label='매출')
axes[0, 0].plot(months, costs, 'r--s', label='비용')
axes[0, 0].set_title('월별 매출/비용 추이')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)

# 2. 카테고리 비율 (원 그래프)
axes[0, 1].pie(cat_values, labels=categories, autopct='%1.1f%%',
               colors=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'])
axes[0, 1].set_title('카테고리별 판매 비율')

# 3. 일일 매출 분포 (히스토그램)
axes[1, 0].hist(daily_sales, bins=10, edgecolor='black', alpha=0.7)
axes[1, 0].set_title('일일 매출 분포')
axes[1, 0].set_xlabel('매출(만원)')
axes[1, 0].set_ylabel('일수')

# 4. 월별 매출 비교 (막대 그래프)
colors = ['#3498db', '#3498db', '#3498db', '#3498db', '#2ecc71', '#2ecc71']
axes[1, 1].bar(months, sales, color=colors)
axes[1, 1].set_title('월별 매출 현황')
axes[1, 1].set_ylabel('매출(만원)')

plt.tight_layout()
plt.savefig('dashboard.png', dpi=150)
plt.show()

💡 실전 팁

✅ 시각화 모범 사례

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import matplotlib.pyplot as plt

# 1. 명확한 제목과 레이블
plt.title('명확한 제목')
plt.xlabel('X축이 무엇인지')
plt.ylabel('Y축이 무엇인지')

# 2. 적절한 색상 선택
# - 대비가 명확한 색상 사용
# - 색맹 친화적 팔레트 고려

# 3. 불필요한 요소 제거
# - 3D 효과 지양
# - 과도한 장식 제거

# 4. 데이터 강조
# - 중요 데이터 하이라이트
# - 적절한 범례 배치

🧪 연습 문제

문제: 종합 시각화 만들기

다음 데이터로 4개 차트가 포함된 대시보드를 만드세요.

1
2
3
4
5
data = {
    '제품': ['노트북', '스마트폰', '태블릿', '이어폰'],
    '1분기': [100, 150, 80, 200],
    '2분기': [120, 160, 90, 220]
}
정답 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

plt.rcParams['font.family'] = 'AppleGothic'

data = {
    '제품': ['노트북', '스마트폰', '태블릿', '이어폰'],
    '1분기': [100, 150, 80, 200],
    '2분기': [120, 160, 90, 220]
}
df = pd.DataFrame(data)

fig, axes = plt.subplots(2, 2, figsize=(12, 10))

# 1. 분기별 비교 (그룹 막대)
x = np.arange(len(df['제품']))
width = 0.35
axes[0, 0].bar(x - width/2, df['1분기'], width, label='1분기')
axes[0, 0].bar(x + width/2, df['2분기'], width, label='2분기')
axes[0, 0].set_xticks(x)
axes[0, 0].set_xticklabels(df['제품'])
axes[0, 0].set_title('분기별 제품 판매량')
axes[0, 0].legend()

# 2. 1분기 비율 (원 그래프)
axes[0, 1].pie(df['1분기'], labels=df['제품'], autopct='%1.1f%%')
axes[0, 1].set_title('1분기 판매 비율')

# 3. 2분기 비율 (도넛 차트)
axes[1, 0].pie(df['2분기'], labels=df['제품'], autopct='%1.1f%%')
centre = plt.Circle((0, 0), 0.5, fc='white')
axes[1, 0].add_patch(centre)
axes[1, 0].set_title('2분기 판매 비율')

# 4. 성장률 (가로 막대)
df['성장률'] = ((df['2분기'] - df['1분기']) / df['1분기'] * 100).round(1)
colors = ['green' if x > 0 else 'red' for x in df['성장률']]
axes[1, 1].barh(df['제품'], df['성장률'], color=colors)
axes[1, 1].set_title('제품별 성장률 (%)')
axes[1, 1].axvline(x=0, color='black', linewidth=0.5)

plt.tight_layout()
plt.show()

📝 오늘 배운 내용 정리

  1. 원/도넛 차트: plt.pie() - 비율 표현
  2. 히스토그램: plt.hist() - 분포 확인
  3. 산점도: plt.scatter() - 상관관계 분석
  4. Pandas 연동: df.plot() - 간편한 시각화
  5. 대시보드: plt.subplots() - 여러 차트 조합

📚 이전 학습

Day 67: Matplotlib 기초 ⭐⭐

📚 다음 학습

Day 69: 데이터 분석 워크플로우 ⭐⭐⭐


“목적에 맞는 차트를 선택하는 것이 시각화의 핵심!” 🎨

Day 68/100 Phase 7: 데이터 분석 기초 #100DaysOfPython
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.