数据可视化 📊
데이터 시각화는 복잡한 데이터를 이해하기 쉬운 그래픽으로 표현하는 과정입니다. Matplotlib은 파이썬에서 가장 널리 사용되는 시각화 라이브러리입니다.
什么是 Matplotlib?
Matplotlib은 파이썬에서 2D 그래프와 차트를 그리는 라이브러리입니다. MATLAB과 유사한 인터페이스를 제공합니다.
主要特点
- 다양한 차트: 선, 막대, 산점도, 히스토그램 등
- 커스터마이징: 세밀한 스타일 조정 가능
- Pandas 통합: DataFrame과 쉽게 연동
- 출판 품질: 논문/보고서용 그래프 생성
安装
pip install matplotlib
import matplotlib.pyplot as plt
import numpy as np
# 한글 폰트 설정 (macOS)
plt.rcParams['font.family'] = 'AppleGothic'
# Windows: 'Malgun Gothic'
# Linux: 'NanumGothic'
# 마이너스 기호 깨짐 방지
plt.rcParams['axes.unicode_minus'] = False
print(f"Matplotlib 버전: {plt.__version__}")
基本图表
折线图 (Line Plot)
import matplotlib.pyplot as plt
import numpy as np
# 데이터 준비
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 그래프 그리기
plt.plot(x, y)
plt.title('사인 함수')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.grid(True)
plt.show()
# 여러 선 그리기
plt.figure(figsize=(10, 6))
plt.plot(x, np.sin(x), label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.title('삼각함수')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True)
plt.show()
스타일 옵션
x = np.linspace(0, 10, 20)
y = x ** 2
# 선 스타일
plt.plot(x, y, 'r--', linewidth=2) # 빨간 점선
plt.plot(x, y, 'bo-', markersize=8) # 파란 동그라미와 선
plt.plot(x, y, 'g^:', alpha=0.5) # 초록 삼각형과 점선 (반투명)
# 더 명시적으로
plt.plot(x, y,
color='blue', # 색상
linestyle='--', # 선 스타일
linewidth=2, # 선 두께
marker='o', # 마커 모양
markersize=8, # 마커 크기
markerfacecolor='red', # 마커 내부 색
markeredgecolor='black',# 마커 테두리 색
alpha=0.7, # 투명도
label='데이터' # 범례
)
柱状图 (Bar Chart)
수직 막대 그래프
import matplotlib.pyplot as plt
# 데이터
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 32]
# 柱状图
plt.figure(figsize=(10, 6))
plt.bar(categories, values, color='skyblue', edgecolor='black')
plt.title('제품별 판매량')
plt.xlabel('제품')
plt.ylabel('판매량')
plt.grid(axis='y', alpha=0.3)
plt.show()
# 색상 다르게
colors = ['red', 'green', 'blue', 'orange', 'purple']
plt.bar(categories, values, color=colors)
plt.show()
수평 막대 그래프
# 수평 막대
plt.figure(figsize=(10, 6))
plt.barh(categories, values, color='lightcoral')
plt.title('제품별 판매량')
plt.xlabel('판매량')
plt.ylabel('제품')
plt.show()
그룹 막대 그래프
import numpy as np
# 데이터
categories = ['A', 'B', 'C', 'D']
values1 = [23, 45, 56, 78]
values2 = [34, 55, 48, 70]
x = np.arange(len(categories))
width = 0.35
# 그룹 막대
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(x - width/2, values1, width, label='2023년', color='skyblue')
ax.bar(x + width/2, values2, width, label='2024년', color='lightcoral')
ax.set_xlabel('제품')
ax.set_ylabel('판매량')
ax.set_title('연도별 제품 판매 비교')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
ax.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()
누적 막대 그래프
# 누적 막대
categories = ['Q1', 'Q2', 'Q3', 'Q4']
product_a = [20, 35, 30, 35]
product_b = [25, 32, 34, 20]
product_c = [15, 20, 25, 30]
plt.figure(figsize=(10, 6))
plt.bar(categories, product_a, label='제품 A')
plt.bar(categories, product_b, bottom=product_a, label='제품 B')
plt.bar(categories, product_c, bottom=np.array(product_a)+np.array(product_b), label='제품 C')
plt.xlabel('분기')
plt.ylabel('판매량')
plt.title('분기별 제품 판매')
plt.legend()
plt.show()
散点图 (Scatter Plot)
import matplotlib.pyplot as plt
import numpy as np
# 데이터
np.random.seed(42)
x = np.random.rand(100) * 100
y = np.random.rand(100) * 100
sizes = np.random.rand(100) * 100
colors = np.random.rand(100)
# 기본 산점도
plt.figure(figsize=(10, 6))
plt.scatter(x, y)
plt.title('기본 산점도')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(True, alpha=0.3)
plt.show()
# 크기와 색상 적용
plt.figure(figsize=(10, 6))
scatter = plt.scatter(x, y, s=sizes, c=colors, cmap='viridis', alpha=0.6)
plt.colorbar(scatter, label='값')
plt.title('크기와 색상을 가진 산점도')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(True, alpha=0.3)
plt.show()
상관관계 시각화
# 키와 몸무게 상관관계
height = np.random.normal(170, 10, 100)
weight = height * 0.8 + np.random.normal(0, 5, 100)
plt.figure(figsize=(10, 6))
plt.scatter(height, weight, alpha=0.5)
plt.title('키와 몸무게 상관관계')
plt.xlabel('키 (cm)')
plt.ylabel('몸무게 (kg)')
# 추세선 추가
z = np.polyfit(height, weight, 1)
p = np.poly1d(z)
plt.plot(height, p(height), "r--", alpha=0.8, label='추세선')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
直方图 (Histogram)
import matplotlib.pyplot as plt
import numpy as np
# 정규분포 데이터
data = np.random.normal(100, 15, 1000)
# 直方图
plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, color='skyblue', edgecolor='black', alpha=0.7)
plt.title('시험 점수 분포')
plt.xlabel('점수')
plt.ylabel('빈도')
plt.axvline(data.mean(), color='red', linestyle='--', linewidth=2, label=f'평균: {data.mean():.1f}')
plt.legend()
plt.grid(axis='y', alpha=0.3)
plt.show()
# 여러 히스토그램 비교
data1 = np.random.normal(100, 15, 1000)
data2 = np.random.normal(110, 10, 1000)
plt.figure(figsize=(10, 6))
plt.hist(data1, bins=30, alpha=0.5, label='A반', color='blue')
plt.hist(data2, bins=30, alpha=0.5, label='B반', color='red')
plt.title('반별 시험 점수 분포')
plt.xlabel('점수')
plt.ylabel('빈도')
plt.legend()
plt.grid(axis='y', alpha=0.3)
plt.show()
饼图 (Pie Chart)
# 데이터
labels = ['Python', 'Java', 'JavaScript', 'C++', 'Others']
sizes = [35, 25, 20, 10, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#ff99cc']
explode = (0.1, 0, 0, 0, 0) # Python 강조
# 饼图
plt.figure(figsize=(10, 8))
plt.pie(sizes, explode=explode, labels=labels, colors=colors,
autopct='%1.1f%%', shadow=True, startangle=90)
plt.title('프로그래밍 언어 사용 비율')
plt.axis('equal')
plt.show()
# 도넛 차트
plt.figure(figsize=(10, 8))
plt.pie(sizes, labels=labels, colors=colors,
autopct='%1.1f%%', startangle=90,
wedgeprops={'width': 0.5}) # 도넛 모양
plt.title('프로그래밍 언어 사용 비율 (도넛)')
plt.axis('equal')
plt.show()
箱线图 (Box Plot)
import numpy as np
# 데이터
np.random.seed(42)
data1 = np.random.normal(100, 10, 200)
data2 = np.random.normal(90, 15, 200)
data3 = np.random.normal(110, 5, 200)
# 箱线图
plt.figure(figsize=(10, 6))
plt.boxplot([data1, data2, data3],
labels=['A반', 'B반', 'C반'],
patch_artist=True,
boxprops=dict(facecolor='lightblue', alpha=0.5),
medianprops=dict(color='red', linewidth=2))
plt.title('반별 시험 점수 분포')
plt.ylabel('점수')
plt.grid(axis='y', alpha=0.3)
plt.show()
子图 (Subplots)
기본 서브플롯
# 2x2 서브플롯
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 왼쪽 위: 선 그래프
x = np.linspace(0, 10, 100)
axes[0, 0].plot(x, np.sin(x))
axes[0, 0].set_title('선 그래프')
axes[0, 0].grid(True)
# 오른쪽 위: 막대 그래프
categories = ['A', 'B', 'C', 'D']
values = [23, 45, 56, 78]
axes[0, 1].bar(categories, values, color='skyblue')
axes[0, 1].set_title('막대 그래프')
# 왼쪽 아래: 산점도
x = np.random.rand(50)
y = np.random.rand(50)
axes[1, 0].scatter(x, y, alpha=0.5)
axes[1, 0].set_title('산점도')
# 오른쪽 아래: 히스토그램
data = np.random.normal(0, 1, 1000)
axes[1, 1].hist(data, bins=30, color='lightcoral')
axes[1, 1].set_title('히스토그램')
plt.tight_layout()
plt.show()
다양한 레이아웃
# 불균등한 서브플롯
fig = plt.figure(figsize=(12, 8))
# 2x2 그리드에서 다양한 크기
ax1 = plt.subplot(2, 2, 1)
ax1.plot([1, 2, 3], [1, 4, 9])
ax1.set_title('Plot 1')
ax2 = plt.subplot(2, 2, 2)
ax2.bar(['A', 'B', 'C'], [10, 20, 15])
ax2.set_title('Plot 2')
ax3 = plt.subplot(2, 1, 2) # 아래쪽 전체
ax3.plot(np.random.rand(100))
ax3.set_title('Plot 3 (Wide)')
plt.tight_layout()
plt.show()
样式设置
기본 스타일
# 사용 가능한 스타일 확인
print(plt.style.available)
# 스타일 적용
plt.style.use('seaborn-v0_8-darkgrid')
# 또는 'ggplot', 'fivethirtyeight', 'bmh' 등
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.figure(figsize=(10, 6))
plt.plot(x, y, linewidth=2)
plt.title('스타일이 적용된 그래프')
plt.show()
# 스타일 초기화
plt.style.use('default')