跳至正文

数据可视化 📊

데이터 시각화는 복잡한 데이터를 이해하기 쉬운 그래픽으로 표현하는 과정입니다. 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')

색상 선택

# 다양한 색상 지정 방법
plt.plot(x, y, color='red') # 이름
plt.plot(x, y, color='r') # 약자
plt.plot(x, y, color='#FF5733') # Hex 코드
plt.plot(x, y, color=(0.1, 0.2, 0.5)) # RGB 튜플
plt.plot(x, y, color=(0.1, 0.2, 0.5, 0.7)) # RGBA (투명도 포함)

# 컬러맵 사용
colors = plt.cm.viridis(np.linspace(0, 1, 10))
for i in range(10):
plt.plot(x, y + i, color=colors[i])

폰트와 텍스트

plt.figure(figsize=(10, 6))

# 타이틀
plt.title('제목', fontsize=20, fontweight='bold', color='navy')

# 축 레이블
plt.xlabel('X축', fontsize=14, style='italic')
plt.ylabel('Y축', fontsize=14, style='italic')

# 텍스트 추가
plt.text(5, 0.5, '주석 텍스트', fontsize=12,
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))

# 화살표와 주석
plt.annotate('중요 지점', xy=(7, 0.7), xytext=(8, 0.9),
arrowprops=dict(arrowstyle='->', color='red', lw=2),
fontsize=12)

plt.plot(x, y)
plt.show()

实战示例

예제 1: 월별 매출 대시보드

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# 데이터 생성
months = ['1월', '2월', '3월', '4월', '5월', '6월']
sales_2023 = [120, 135, 148, 162, 155, 178]
sales_2024 = [145, 158, 170, 185, 192, 205]
target = [150] * 6

# 대시보드 생성
fig = plt.figure(figsize=(16, 10))
fig.suptitle('2024년 상반기 매출 분석 대시보드', fontsize=20, fontweight='bold')

# 1. 월별 매출 비교 (선 그래프)
ax1 = plt.subplot(2, 3, 1)
ax1.plot(months, sales_2023, marker='o', linewidth=2, label='2023년', color='skyblue')
ax1.plot(months, sales_2024, marker='s', linewidth=2, label='2024년', color='coral')
ax1.plot(months, target, linestyle='--', linewidth=2, label='목표', color='green')
ax1.set_title('월별 매출 추이', fontsize=14, fontweight='bold')
ax1.set_ylabel('매출 (백만원)')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 2. 연도별 총 매출 (막대 그래프)
ax2 = plt.subplot(2, 3, 2)
total_sales = [sum(sales_2023), sum(sales_2024)]
colors = ['skyblue', 'coral']
bars = ax2.bar(['2023년', '2024년'], total_sales, color=colors, edgecolor='black', linewidth=2)
ax2.set_title('연도별 총 매출', fontsize=14, fontweight='bold')
ax2.set_ylabel('매출 (백만원)')
for bar in bars:
height = bar.get_height()
ax2.text(bar.get_x() + bar.get_width()/2., height,
f'{int(height)}M', ha='center', va='bottom', fontsize=12, fontweight='bold')
ax2.grid(axis='y', alpha=0.3)

# 3. 증감율 (막대 그래프)
ax3 = plt.subplot(2, 3, 3)
growth = [(s24 - s23) / s23 * 100 for s23, s24 in zip(sales_2023, sales_2024)]
colors_growth = ['green' if g > 0 else 'red' for g in growth]
ax3.bar(months, growth, color=colors_growth, alpha=0.7, edgecolor='black')
ax3.axhline(y=0, color='black', linestyle='-', linewidth=0.5)
ax3.set_title('전년 대비 증감율', fontsize=14, fontweight='bold')
ax3.set_ylabel('증감율 (%)')
ax3.grid(axis='y', alpha=0.3)

# 4. 목표 달성률 (수평 막대)
ax4 = plt.subplot(2, 3, 4)
achievement = [s / t * 100 for s, t in zip(sales_2024, target)]
colors_achievement = ['green' if a >= 100 else 'orange' for a in achievement]
ax4.barh(months, achievement, color=colors_achievement, alpha=0.7, edgecolor='black')
ax4.axvline(x=100, color='red', linestyle='--', linewidth=2, label='목표선')
ax4.set_title('월별 목표 달성률', fontsize=14, fontweight='bold')
ax4.set_xlabel('달성률 (%)')
ax4.legend()
ax4.grid(axis='x', alpha=0.3)

# 5. 매출 분포 (히스토그램)
ax5 = plt.subplot(2, 3, 5)
all_sales = sales_2023 + sales_2024
ax5.hist(all_sales, bins=10, color='mediumpurple', edgecolor='black', alpha=0.7)
ax5.axvline(np.mean(all_sales), color='red', linestyle='--',
linewidth=2, label=f'평균: {np.mean(all_sales):.1f}M')
ax5.set_title('매출 분포', fontsize=14, fontweight='bold')
ax5.set_xlabel('매출 (백만원)')
ax5.set_ylabel('빈도')
ax5.legend()
ax5.grid(axis='y', alpha=0.3)

# 6. 통계 요약 (텍스트)
ax6 = plt.subplot(2, 3, 6)
ax6.axis('off')

stats_text = f"""
📊 주요 지표 요약

2024년 총 매출: {sum(sales_2024):,}백만원
2023년 총 매출: {sum(sales_2023):,}백만원
증감: +{sum(sales_2024) - sum(sales_2023):,}백만원
증감율: +{(sum(sales_2024) - sum(sales_2023)) / sum(sales_2023) * 100:.1f}%

월평균 매출: {np.mean(sales_2024):.1f}백만원
최고 매출: {max(sales_2024)}백만원 ({months[sales_2024.index(max(sales_2024))]})
최저 매출: {min(sales_2024)}백만원 ({months[sales_2024.index(min(sales_2024))]})

목표 달성 월수: {sum(1 for s in sales_2024 if s >= 150)}/6개월
평균 달성률: {np.mean(achievement):.1f}%
"""

ax6.text(0.1, 0.5, stats_text, fontsize=12, verticalalignment='center',
fontfamily='monospace',
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.3))

plt.tight_layout()
plt.show()

예제 2: 제품 판매 분석

import matplotlib.pyplot as plt
import pandas as pd

# 제품 판매 데이터
data = {
'제품': ['노트북', '마우스', '키보드', '모니터', '헤드셋'],
'판매량': [450, 1200, 800, 350, 600],
'매출': [450000, 36000, 80000, 350000, 180000],
'재고': [120, 450, 280, 90, 200]
}
df = pd.DataFrame(data)

# 대시보드
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('제품 판매 현황', fontsize=18, fontweight='bold')

# 1. 제품별 판매량
axes[0, 0].bar(df['제품'], df['판매량'], color='steelblue', edgecolor='black')
axes[0, 0].set_title('제품별 판매량', fontsize=14, fontweight='bold')
axes[0, 0].set_ylabel('판매량')
axes[0, 0].tick_params(axis='x', rotation=45)
axes[0, 0].grid(axis='y', alpha=0.3)

# 2. 제품별 매출
colors = plt.cm.Set3(range(len(df)))
axes[0, 1].barh(df['제품'], df['매출'], color=colors, edgecolor='black')
axes[0, 1].set_title('제품별 매출', fontsize=14, fontweight='bold')
axes[0, 1].set_xlabel('매출 (원)')
for i, v in enumerate(df['매출']):
axes[0, 1].text(v, i, f' {v:,}', va='center', fontsize=10)
axes[0, 1].grid(axis='x', alpha=0.3)

# 3. 매출 비율 (파이 차트)
explode = [0.05] * len(df)
explode[df['매출'].idxmax()] = 0.15 # 최대 매출 제품 강조
axes[1, 0].pie(df['매출'], labels=df['제품'], autopct='%1.1f%%',
explode=explode, shadow=True, startangle=90)
axes[1, 0].set_title('매출 비율', fontsize=14, fontweight='bold')

# 4. 판매량 vs 재고 (산점도)
axes[1, 1].scatter(df['판매량'], df['재고'], s=df['매출']/500,
c=range(len(df)), cmap='viridis', alpha=0.6, edgecolors='black', linewidth=2)
for i, txt in enumerate(df['제품']):
axes[1, 1].annotate(txt, (df['판매량'][i], df['재고'][i]),
xytext=(5, 5), textcoords='offset points', fontsize=10)
axes[1, 1].set_title('판매량 vs 재고 (크기=매출)', fontsize=14, fontweight='bold')
axes[1, 1].set_xlabel('판매량')
axes[1, 1].set_ylabel('재고')
axes[1, 1].grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

예제 3: 시계열 데이터 시각화

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# 일일 방문자 데이터 생성
dates = pd.date_range('2024-01-01', '2024-06-30', freq='D')
np.random.seed(42)
base_visitors = 1000
trend = np.linspace(0, 500, len(dates))
seasonality = 200 * np.sin(2 * np.pi * np.arange(len(dates)) / 7) # 주간 패턴
noise = np.random.normal(0, 50, len(dates))
visitors = base_visitors + trend + seasonality + noise

df = pd.DataFrame({
'date': dates,
'visitors': visitors.astype(int)
})
df['month'] = df['date'].dt.month
df['weekday'] = df['date'].dt.day_name()

# 시각화
fig = plt.figure(figsize=(16, 12))
fig.suptitle('웹사이트 방문자 분석 (2024년 상반기)', fontsize=20, fontweight='bold')

# 1. 전체 추이
ax1 = plt.subplot(3, 2, 1)
ax1.plot(df['date'], df['visitors'], linewidth=1, alpha=0.7, label='일일 방문자')
# 이동 평균
ma7 = df['visitors'].rolling(window=7).mean()
ma30 = df['visitors'].rolling(window=30).mean()
ax1.plot(df['date'], ma7, linewidth=2, label='7일 이동평균', color='orange')
ax1.plot(df['date'], ma30, linewidth=2, label='30일 이동평균', color='red')
ax1.set_title('일일 방문자 추이', fontsize=14, fontweight='bold')
ax1.set_ylabel('방문자 수')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 2. 월별 평균
ax2 = plt.subplot(3, 2, 2)
monthly_avg = df.groupby('month')['visitors'].mean()
month_names = ['1월', '2월', '3월', '4월', '5월', '6월']
bars = ax2.bar(month_names, monthly_avg, color='skyblue', edgecolor='black')
ax2.set_title('월별 평균 방문자', fontsize=14, fontweight='bold')
ax2.set_ylabel('평균 방문자 수')
for bar in bars:
height = bar.get_height()
ax2.text(bar.get_x() + bar.get_width()/2., height,
f'{int(height)}', ha='center', va='bottom', fontsize=10)
ax2.grid(axis='y', alpha=0.3)

# 3. 요일별 패턴
ax3 = plt.subplot(3, 2, 3)
weekday_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
weekday_labels = ['월', '화', '수', '목', '금', '토', '일']
weekday_avg = df.groupby('weekday')['visitors'].mean().reindex(weekday_order)
colors = ['#FF6B6B' if day in ['Saturday', 'Sunday'] else '#4ECDC4' for day in weekday_order]
ax3.bar(weekday_labels, weekday_avg, color=colors, edgecolor='black')
ax3.set_title('요일별 평균 방문자', fontsize=14, fontweight='bold')
ax3.set_ylabel('평균 방문자 수')
ax3.grid(axis='y', alpha=0.3)

# 4. 방문자 분포
ax4 = plt.subplot(3, 2, 4)
ax4.hist(df['visitors'], bins=30, color='mediumpurple', edgecolor='black', alpha=0.7)
ax4.axvline(df['visitors'].mean(), color='red', linestyle='--',
linewidth=2, label=f"평균: {df['visitors'].mean():.0f}")
ax4.axvline(df['visitors'].median(), color='green', linestyle='--',
linewidth=2, label=f"중앙값: {df['visitors'].median():.0f}")
ax4.set_title('방문자 분포', fontsize=14, fontweight='bold')
ax4.set_xlabel('방문자 수')
ax4.set_ylabel('일수')
ax4.legend()
ax4.grid(axis='y', alpha=0.3)

# 5. 월별 박스플롯
ax5 = plt.subplot(3, 2, 5)
monthly_data = [df[df['month'] == m]['visitors'].values for m in range(1, 7)]
bp = ax5.boxplot(monthly_data, labels=month_names, patch_artist=True)
for patch in bp['boxes']:
patch.set_facecolor('lightblue')
ax5.set_title('월별 방문자 분포', fontsize=14, fontweight='bold')
ax5.set_ylabel('방문자 수')
ax5.grid(axis='y', alpha=0.3)

# 6. 통계 요약
ax6 = plt.subplot(3, 2, 6)
ax6.axis('off')

stats = f"""
📈 방문자 통계 요약

총 분석 기간: {len(df)}
총 방문자: {df['visitors'].sum():,}

평균 방문자: {df['visitors'].mean():.0f}
중앙값: {df['visitors'].median():.0f}
표준편차: {df['visitors'].std():.0f}

최대 방문: {df['visitors'].max()}
({df[df['visitors'] == df['visitors'].max()]['date'].dt.date.values[0]})
최소 방문: {df['visitors'].min()}
({df[df['visitors'] == df['visitors'].min()]['date'].dt.date.values[0]})

가장 많은 요일: {weekday_labels[weekday_avg.argmax()]}요일
가장 적은 요일: {weekday_labels[weekday_avg.argmin()]}요일

증가 추세: +{(df['visitors'].iloc[-30:].mean() - df['visitors'].iloc[:30].mean()):.0f}
"""

ax6.text(0.1, 0.5, stats, fontsize=11, verticalalignment='center',
fontfamily='monospace',
bbox=dict(boxstyle='round', facecolor='lightyellow', alpha=0.5))

plt.tight_layout()
plt.show()

保存和导出

import matplotlib.pyplot as plt

# 그래프 생성
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
ax.set_title('샘플 그래프')

# 이미지로 저장
plt.savefig('graph.png', dpi=300, bbox_inches='tight') # PNG
plt.savefig('graph.pdf', bbox_inches='tight') # PDF
plt.savefig('graph.svg', bbox_inches='tight') # SVG

# 투명 배경
plt.savefig('graph.png', dpi=300, bbox_inches='tight', transparent=True)

plt.close() # 메모리 정리

常见问题

한글이 깨져요!

import matplotlib.pyplot as plt

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

# Windows
plt.rcParams['font.family'] = 'Malgun Gothic'

# Linux
plt.rcParams['font.family'] = 'NanumGothic'

# 마이너스 기호 깨짐 방지
plt.rcParams['axes.unicode_minus'] = False

그래프가 겹쳐요!

# tight_layout 사용
plt.tight_layout()

# 또는 여백 조정
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1,
wspace=0.3, hspace=0.3)

고해상도 이미지를 만들고 싶어요!

# DPI(인치당 도트 수) 높이기
fig = plt.figure(figsize=(10, 6), dpi=300)

# 또는 저장 시
plt.savefig('graph.png', dpi=300)

Pandas DataFrame을 바로 그릴 수 있나요?

import pandas as pd

df = pd.DataFrame({
'A': [1, 2, 3, 4],
'B': [4, 3, 2, 1]
})

# Pandas의 plot 메서드
df.plot(kind='line')
df.plot(kind='bar')
df.plot(kind='scatter', x='A', y='B')
plt.show()

下一步

Matplotlib 기초를 익혔다면:

  1. Seaborn: 더 아름다운 통계 그래프
  2. Plotly: 인터랙티브 시각화
  3. 대시보드: Streamlit, Dash로 웹 대시보드
  4. 고급 시각화: 3D 그래프, 애니메이션

参考资料