Matplotlib 파이 차트: Python에서 파이 차트를 만드는 완전 가이드
Updated on
효과적인 데이터 시각화는 인사이트를 명확하게 전달하는 데 필수적입니다. 전체에서 각 부분이 차지하는 비율이나 퍼센트를 보여줘야 할 때 파이 차트는 시각화 도구 상자에서 중요한 도구가 됩니다. 하지만 많은 데이터 분석가들이 중요한 구간을 제대로 강조하고, 적절한 색을 사용하며, 퍼센트를 정확히 표시하는 “전문적으로 보이는” 파이 차트를 만드는 데 어려움을 겪습니다. 기본 matplotlib 파이 차트는 대개 밋밋해 보이고, 맥락이 부족하며, 핵심 데이터 포인트를 강조하지 못하는 경우가 많습니다.
이런 시각화 문제는 시장 점유율 분포, 예산 배분, 설문 응답 분해 결과처럼 이해관계자들이 빠르게 파악해야 하는 내용을 발표할 때 더 두드러집니다. 잘못 설계된 파이 차트는 오히려 혼란을 주어 중요한 비즈니스 지표를 잘못 해석하게 만들 수 있습니다.
Matplotlib는 기본 원형 차트를 전문가 수준의 시각화로 바꿀 수 있는 폭넓은 커스터마이징 옵션을 갖춘 plt.pie() 함수를 제공합니다. 이 가이드에서는 단순한 비율 차트부터 복잡한 중첩 다이어그램까지 파이 차트를 만드는 방법을 다루며, 라벨, 색상, 분리(explode) 조각, 도넛 차트, 그리고 실제 데이터 분석 워크플로에서 자주 쓰는 pandas DataFrame 연동까지 실전 예제로 설명합니다.
기본 Matplotlib 파이 차트 문법
matplotlib에서 파이 차트를 만드는 기본은 plt.pie()이며, 각 조각의 크기를 나타내는 값 리스트(또는 배열)만 있으면 됩니다.
import matplotlib.pyplot as plt
# Basic pie chart data
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
# Create pie chart
plt.pie(sizes, labels=labels)
plt.title('Market Share Distribution')
plt.show()위 코드는 sizes 리스트의 값에 비례해 조각 크기가 결정되는 기본 원형 차트를 생성합니다. Matplotlib가 각 구간의 퍼센트와 각도를 자동으로 계산합니다. 색상은 기본 컬러 사이클에서 자동 할당되는데, 발표 목적에 따라서는 적합하지 않을 수 있습니다.
타원처럼 보이지 않고 정확한 원형으로 보이게 하려면 plt.axis('equal')을 추가하세요.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
plt.pie(sizes, labels=labels)
plt.axis('equal') # Equal aspect ratio ensures circular shape
plt.title('Market Share Distribution')
plt.show()autopct로 퍼센트 표시하기
autopct 파라미터는 각 조각에 퍼센트 값을 자동으로 포맷팅해 표시해 주므로, 수동 계산 없이도 정보를 더 풍부하게 만들 수 있습니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D'
plt.pie(sizes, labels=labels, autopct='%1.1f%%')
plt.axis('equal')
plt.title('Market Share with Percentages')
plt.show()포맷 문자열 '%1.1f%%'는 소수점 한 자리까지 퍼센트를 표시합니다. 첫 번째 %는 포맷 지정자의 시작이고, 1.1f는 소수점 앞 1자리/뒤 1자리를 의미하며, %%는 결과에 % 기호를 문자 그대로 출력합니다.
소수점 없이 정수 퍼센트로 표시하려면 '%1.0f%%'를 사용합니다.
plt.pie(sizes, labels=labels, autopct='%1.0f%%')또한 autopct에 커스텀 함수를 넘겨 퍼센트 표시를 더 세밀하게 제어할 수도 있습니다.
import matplotlib.pyplot as plt
sizes = [350, 250, 200, 200]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
def make_autopct(values):
def my_autopct(pct):
total = sum(values)
val = int(round(pct * total / 100.0))
return f'{pct:.1f}%\n({val:d})'
return my_autopct
plt.pie(sizes, labels=labels, autopct=make_autopct(sizes))
plt.axis('equal')
plt.title('Market Share with Counts and Percentages')
plt.show()이렇게 하면 각 조각에 퍼센트와 실제 개수(카운트)를 함께 표시할 수 있습니다.
커스텀 색상과 컬러맵
colors 파라미터는 matplotlib 기본 컬러 사이클을 덮어쓰기 위한 색상 목록을 받습니다. 색상 이름, hex 코드, RGB 튜플 등을 사용할 수 있습니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%')
plt.axis('equal')
plt.title('Market Share with Custom Colors')
plt.show()데이터에 기반한 색상 선택이 필요하다면 matplotlib 컬러맵을 사용할 수 있습니다.
import matplotlib.pyplot as plt
import numpy as np
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
# Generate colors from a colormap
cmap = plt.cm.Set3
colors = cmap(np.linspace(0, 1, len(sizes)))
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%')
plt.axis('equal')
plt.title('Market Share with Colormap')
plt.show()파이 차트에 자주 쓰이는 컬러맵으로는 Set1, Set2, Set3, Pastel1, Pastel2, tab10 등이 있습니다.
강조를 위한 조각 분리(explode)
explode 파라미터는 특정 조각을 중심에서 분리해 중요한 데이터 포인트를 강조합니다. explode 튜플의 각 값은 해당 조각의 반경 방향 오프셋(밀어내는 정도)을 의미합니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
explode = (0.1, 0, 0, 0) # Explode the first slice
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
explode=explode)
plt.axis('equal')
plt.title('Market Share with Exploded Slice')
plt.show()0.1은 첫 번째 조각을 반지름의 10%만큼 바깥으로 이동시킵니다. 여러 조각을 동시에 분리할 수도 있습니다.
explode = (0.1, 0.05, 0, 0) # Explode first two slices
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
explode=explode)그림자(shadow)와 시작 각도(startangle) 추가
shadow는 입체감을 주는 드롭 섀도우를 추가하고, startangle은 전체 차트를 회전시켜 조각이 시작되는 위치를 조정합니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
explode = (0.1, 0, 0, 0)
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
explode=explode, shadow=True, startangle=90)
plt.axis('equal')
plt.title('Market Share with Shadow and Rotation')
plt.show()startangle=90은 기본값 0도(원 오른쪽) 대신, 첫 조각이 90도(원 위쪽)에서 시작하도록 회전시킵니다. 중요한 조각을 상단에 배치해 가시성을 높일 때 유용합니다.
도넛 차트 만들기
도넛 차트는 가운데가 비어 있는 파이 차트이며, wedgeprops로 각 웨지의 두께(width)를 조정해 만들 수 있습니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
# Create donut chart
wedgeprops = {'width': 0.4}
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
wedgeprops=wedgeprops)
plt.axis('equal')
plt.title('Market Share Donut Chart')
plt.show()width가 0.4이면 반지름의 40% 두께를 가진 링이 됩니다. 값이 작을수록 링은 더 얇아지고, 1.0에 가까울수록 일반 파이 차트에 가까워집니다.
도넛 중앙에 텍스트를 추가할 수도 있습니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
wedgeprops = {'width': 0.4, 'edgecolor': 'white', 'linewidth': 2}
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
wedgeprops=wedgeprops)
plt.axis('equal')
# Add center text
plt.text(0, 0, 'Total\nSales', ha='center', va='center',
fontsize=14, fontweight='bold')
plt.title('Market Share Donut Chart')
plt.show()중첩/동심 파이 차트
서로 다른 반지름으로 여러 개의 파이 차트를 겹쳐 그리면, 계층적 관계를 표현하는 복합 시각화를 만들 수 있습니다.
import matplotlib.pyplot as plt
import numpy as np
# Outer ring data
outer_sizes = [35, 25, 20, 20]
outer_labels = ['Product A', 'Product B', 'Product C', 'Product D']
outer_colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
# Inner ring data (subcategories)
inner_sizes = [15, 20, 12, 13, 10, 10, 8, 12]
inner_labels = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2']
inner_colors = ['#ffcccc', '#ff6666', '#99ccff', '#3399ff',
'#ccffcc', '#66ff66', '#ffe6cc', '#ffb366']
fig, ax = plt.subplots()
# Outer pie
ax.pie(outer_sizes, labels=outer_labels, colors=outer_colors,
autopct='%1.1f%%', radius=1.2, wedgeprops={'width': 0.4})
# Inner pie
ax.pie(inner_sizes, labels=inner_labels, colors=inner_colors,
autopct='%1.0f%%', radius=0.8, wedgeprops={'width': 0.4})
ax.axis('equal')
plt.title('Nested Pie Chart: Products and Subcategories')
plt.show()이 예시는 바깥 링이 제품, 안쪽 링이 각 제품의 하위 카테고리를 나타내는 동심 도넛 차트 2개를 생성합니다.
범례(legend) 추가
조각이 많거나 라벨이 시각화를 어지럽힐 때는, 조각 라벨을 범례로 옮기는 방식이 좋습니다. legend()를 사용하세요.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 15, 5]
labels = ['Product A', 'Product B', 'Product C', 'Product D', 'Others']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#ff99cc']
plt.pie(sizes, colors=colors, autopct='%1.1f%%', startangle=90)
plt.axis('equal')
plt.legend(labels, loc='upper left', bbox_to_anchor=(1, 0, 0.5, 1))
plt.title('Market Share Distribution')
plt.tight_layout()
plt.show()bbox_to_anchor로 범례를 차트 영역 밖에 배치할 수 있습니다. tight_layout()은 범례가 잘리지 않도록 레이아웃을 조정합니다.
퍼센트를 포함한 커스텀 범례 항목이 필요하다면 다음처럼 만들 수 있습니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 15, 5]
labels = ['Product A', 'Product B', 'Product C', 'Product D', 'Others']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#ff99cc']
wedges, texts, autotexts = plt.pie(sizes, colors=colors, autopct='%1.1f%%',
startangle=90)
plt.axis('equal')
# Create legend with labels and percentages
legend_labels = [f'{label} ({size}%)' for label, size in zip(labels, sizes)]
plt.legend(wedges, legend_labels, loc='upper left',
bbox_to_anchor=(1, 0, 0.5, 1))
plt.title('Market Share Distribution')
plt.tight_layout()
plt.show()파이 차트 파라미터 레퍼런스
| Parameter | Type | Description | Example |
|---|---|---|---|
x | array-like | 조각 크기(필수) | [30, 25, 20, 25] |
labels | list of str | 각 조각의 텍스트 라벨 | ['A', 'B', 'C', 'D'] |
colors | list | 각 조각의 색상 | ['red', 'blue', 'green'] |
autopct | str or function | 퍼센트 포맷 문자열 또는 함수 | '%1.1f%%' |
explode | tuple | 각 조각의 반경 오프셋 | (0.1, 0, 0, 0) |
shadow | bool | 드롭 섀도우 추가 | True or False |
startangle | float | 회전 각도(도) | 90 |
radius | float | 파이 차트 반지름 | 1.0 (default) |
wedgeprops | dict | wedge patch 속성 | {'width': 0.4} |
textprops | dict | 텍스트 라벨 속성 | {'fontsize': 12} |
labeldistance | float | 라벨의 중심으로부터 거리 | 1.1 (default) |
pctdistance | float | 퍼센트 텍스트의 중심으로부터 거리 | 0.6 (default) |
counterclock | bool | 조각 진행 방향 | True (default) |
frame | bool | 축 프레임 표시 | False (default) |
텍스트 속성 커스터마이징
textprops 파라미터는 라벨과 퍼센트를 포함해 파이 차트의 모든 텍스트 요소 스타일을 제어합니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
textprops = {'fontsize': 14, 'fontweight': 'bold', 'color': 'darkblue'}
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
textprops=textprops)
plt.axis('equal')
plt.title('Market Share with Custom Text', fontsize=16, fontweight='bold')
plt.show()라벨 텍스트와 퍼센트 텍스트를 따로 제어하려면 반환되는 텍스트 객체에 접근하면 됩니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
wedges, texts, autotexts = plt.pie(sizes, labels=labels, colors=colors,
autopct='%1.1f%%')
# Customize label text
for text in texts:
text.set_fontsize(12)
text.set_fontweight('bold')
# Customize percentage text
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontsize(10)
autotext.set_fontweight('bold')
plt.axis('equal')
plt.title('Market Share with Styled Text')
plt.show()Pandas DataFrames와 함께 사용하기
실무 데이터 분석은 대개 pandas DataFrame을 기반으로 합니다. DataFrame 컬럼에서 바로 파이 차트를 만들 수 있습니다.
import matplotlib.pyplot as plt
import pandas as pd
# Sample DataFrame
data = {
'Product': ['Product A', 'Product B', 'Product C', 'Product D'],
'Sales': [350000, 250000, 200000, 200000]
}
df = pd.DataFrame(data)
# Create pie chart from DataFrame
plt.pie(df['Sales'], labels=df['Product'], autopct='%1.1f%%',
startangle=90)
plt.axis('equal')
plt.title('Sales Distribution by Product')
plt.show()그룹 단위로 집계가 필요하면, 시각화 전에 pandas로 집계를 수행하세요.
import matplotlib.pyplot as plt
import pandas as pd
# Sample DataFrame with categories
data = {
'Region': ['North', 'South', 'East', 'West', 'North', 'South', 'East', 'West'],
'Product': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'],
'Sales': [120000, 80000, 95000, 105000, 90000, 110000, 85000, 95000]
}
df = pd.DataFrame(data)
# Group by region and sum sales
region_sales = df.groupby('Region')['Sales'].sum()
plt.pie(region_sales.values, labels=region_sales.index, autopct='%1.1f%%',
startangle=90)
plt.axis('equal')
plt.title('Total Sales by Region')
plt.show()파이 차트를 파일로 저장하기
plt.show()를 호출하기 전에 plt.savefig()를 사용하면 다양한 이미지 포맷으로 저장할 수 있습니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%')
plt.axis('equal')
plt.title('Market Share Distribution')
# Save as PNG with high DPI
plt.savefig('market_share.png', dpi=300, bbox_inches='tight')
# Save as PDF for vector graphics
plt.savefig('market_share.pdf', bbox_inches='tight')
# Save as SVG for web use
plt.savefig('market_share.svg', bbox_inches='tight')
plt.show()bbox_inches='tight'는 차트 주변의 불필요한 여백을 줄여줍니다. dpi는 PNG 같은 래스터 포맷의 해상도를 제어합니다.
실무 예시: 예산 구성(Budget Breakdown)
import matplotlib.pyplot as plt
import pandas as pd
# Annual budget data
budget_data = {
'Category': ['Salaries', 'Marketing', 'Operations', 'R&D', 'Infrastructure'],
'Amount': [450000, 180000, 120000, 150000, 100000]
}
df = pd.DataFrame(budget_data)
# Calculate total budget
total_budget = df['Amount'].sum()
# Define colors
colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#f9ca24', '#6c5ce7']
# Create pie chart
fig, ax = plt.subplots(figsize=(10, 7))
wedges, texts, autotexts = ax.pie(df['Amount'], labels=df['Category'],
colors=colors, autopct='%1.1f%%',
startangle=90, explode=(0.05, 0, 0, 0, 0))
# Customize text
for text in texts:
text.set_fontsize(12)
text.set_fontweight('bold')
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontsize(10)
autotext.set_fontweight('bold')
ax.axis('equal')
plt.title(f'Annual Budget Breakdown\nTotal: ${total_budget:,}',
fontsize=16, fontweight='bold', pad=20)
plt.tight_layout()
plt.savefig('budget_breakdown.png', dpi=300, bbox_inches='tight')
plt.show()실무 예시: 설문 결과(Survey Results)
import matplotlib.pyplot as plt
import numpy as np
# Survey response data
responses = {
'Very Satisfied': 145,
'Satisfied': 230,
'Neutral': 85,
'Dissatisfied': 30,
'Very Dissatisfied': 10
}
labels = list(responses.keys())
sizes = list(responses.values())
total_responses = sum(sizes)
# Color scheme from red to green
colors = ['#2ecc71', '#3498db', '#95a5a6', '#e67e22', '#e74c3c']
fig, ax = plt.subplots(figsize=(10, 7))
wedges, texts, autotexts = ax.pie(sizes, labels=labels, colors=colors,
autopct=lambda pct: f'{pct:.1f}%\n({int(pct * total_responses / 100)})',
startangle=90, wedgeprops={'edgecolor': 'white', 'linewidth': 2})
for text in texts:
text.set_fontsize(11)
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontsize(9)
autotext.set_fontweight('bold')
ax.axis('equal')
plt.title(f'Customer Satisfaction Survey Results\nTotal Responses: {total_responses}',
fontsize=16, fontweight='bold', pad=20)
plt.tight_layout()
plt.show()실무 예시: 시장 점유율 분석(Market Share Analysis)
import matplotlib.pyplot as plt
import pandas as pd
# Market share data for multiple quarters
data = {
'Company': ['Company A', 'Company B', 'Company C', 'Company D', 'Others'],
'Q1_Share': [28, 24, 18, 15, 15],
'Q2_Share': [30, 22, 19, 14, 15],
'Q3_Share': [32, 21, 18, 15, 14],
'Q4_Share': [35, 20, 17, 16, 12]
}
df = pd.DataFrame(data)
# Create subplots for each quarter
fig, axes = plt.subplots(2, 2, figsize=(14, 12))
quarters = ['Q1_Share', 'Q2_Share', 'Q3_Share', 'Q4_Share']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#ff99cc']
for idx, (ax, quarter) in enumerate(zip(axes.flat, quarters)):
wedges, texts, autotexts = ax.pie(df[quarter], labels=df['Company'],
colors=colors, autopct='%1.1f%%',
startangle=90)
for text in texts:
text.set_fontsize(10)
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontsize(9)
autotext.set_fontweight('bold')
ax.set_title(f'Market Share {quarter.replace("_Share", "")}',
fontsize=12, fontweight='bold')
plt.suptitle('Quarterly Market Share Analysis', fontsize=16, fontweight='bold', y=0.995)
plt.tight_layout()
plt.savefig('market_share_analysis.png', dpi=300, bbox_inches='tight')
plt.show()파이 차트를 다른 시각화와 결합하기
파이 차트와 막대/선/테이블 등을 함께 사용해 대시보드를 구성할 수 있습니다.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# Sample data
categories = ['Product A', 'Product B', 'Product C', 'Product D']
current_sales = [350000, 250000, 200000, 200000]
previous_sales = [320000, 280000, 180000, 220000]
# Create figure with subplots
fig = plt.figure(figsize=(14, 6))
# Pie chart showing current market share
ax1 = plt.subplot(1, 2, 1)
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
ax1.pie(current_sales, labels=categories, colors=colors, autopct='%1.1f%%',
startangle=90)
ax1.set_title('Current Market Share', fontsize=14, fontweight='bold')
# Bar chart showing comparison
ax2 = plt.subplot(1, 2, 2)
x = np.arange(len(categories))
width = 0.35
bars1 = ax2.bar(x - width/2, previous_sales, width, label='Previous Period',
color='#95a5a6', alpha=0.8)
bars2 = ax2.bar(x + width/2, current_sales, width, label='Current Period',
color='#3498db', alpha=0.8)
ax2.set_xlabel('Products', fontsize=12, fontweight='bold')
ax2.set_ylabel('Sales ($)', fontsize=12, fontweight='bold')
ax2.set_title('Sales Comparison', fontsize=14, fontweight='bold')
ax2.set_xticks(x)
ax2.set_xticklabels(categories)
ax2.legend()
ax2.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.savefig('combined_visualization.png', dpi=300, bbox_inches='tight')
plt.show()파이 차트 vs 막대 차트: 언제 무엇을 써야 할까?
파이 차트는 특정 상황에서 효과적이지만, 값 비교가 목적이라면 막대 차트가 더 명확한 경우가 많습니다.
파이 차트를 쓰기 좋은 경우:
- 전체에서 부분의 비중을 보여줄 때(퍼센트 합이 100%여야 함)
- 카테고리가 5개 이하일 때
- 1~2개의 지배적인 구간을 강조하고 싶을 때
- 정확한 비율보다 “대략적인 구성”이 중요할 때
- 경영진용 하이레벨 요약을 만들 때
막대 차트를 쓰기 좋은 경우:
- 카테고리 간 값을 비교할 때
- 5개를 넘는 카테고리를 보여줄 때
- 정밀한 값 비교가 필요할 때
- 값의 합이 의미 있는 전체를 구성하지 않을 때
- 시간에 따른 추세를 보여줄 때
- 이해관계자가 비슷한 크기의 구간을 비교해야 할 때
비교 예시:
import matplotlib.pyplot as plt
data = {'Category A': 23, 'Category B': 19, 'Category C': 18,
'Category D': 17, 'Category E': 13, 'Category F': 10}
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# Pie chart
ax1.pie(data.values(), labels=data.keys(), autopct='%1.1f%%', startangle=90)
ax1.set_title('Pie Chart: Harder to Compare Similar Values', fontweight='bold')
# Bar chart
ax2.bar(data.keys(), data.values(), color='#3498db')
ax2.set_ylabel('Value', fontweight='bold')
ax2.set_title('Bar Chart: Easier to Compare Similar Values', fontweight='bold')
ax2.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()막대 차트는 카테고리 간의 작은 차이를 파이 차트보다 훨씬 더 분명하게 드러냅니다.
PyGWalker로 인터랙티브 파이 차트 만들기
탐색적 데이터 분석에서 인터랙티브 시각화가 필요하다면, PyGWalker (opens in a new tab)를 통해 pandas DataFrames를 드래그 앤 드롭으로 파이 차트를 만들 수 있는 Tableau 스타일의 인터페이스로 변환할 수 있습니다.
import pandas as pd
import pygwalker as pyg
# Sample DataFrame
data = {
'Product': ['Product A', 'Product B', 'Product C', 'Product D', 'Product E'],
'Sales': [350000, 250000, 200000, 200000, 150000],
'Region': ['North', 'South', 'East', 'West', 'North']
}
df = pd.DataFrame(data)
# Launch interactive visualization interface
walker = pyg.walk(df)PyGWalker를 사용하면 코딩 경험이 없는 비즈니스 분석가도 파이 차트를 포함한 다양한 시각화를 인터랙티브하게 만들 수 있고, 데이터를 동적으로 필터링하며, 발표용 결과물을 내보낼 수 있습니다. 복잡한 집계와 내장 통계 요약을 지원하므로, matplotlib로 프로덕션 시각화를 확정하기 전 빠르게 프로토타이핑할 때 유용합니다.
고급 커스터마이징: 테두리 색과 선 스타일
wedgeprops를 사용해 조각 사이를 시각적으로 분리하는 테두리 색상과 선 굵기를 지정할 수 있습니다.
import matplotlib.pyplot as plt
sizes = [35, 25, 20, 20]
labels = ['Product A', 'Product B', 'Product C', 'Product D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
wedgeprops = {
'edgecolor': 'black',
'linewidth': 2,
'linestyle': '-',
'antialiased': True
}
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
startangle=90, wedgeprops=wedgeprops)
plt.axis('equal')
plt.title('Market Share with Edge Styling')
plt.show()더 은은한 효과를 원하면 흰색 테두리를 사용하세요.
wedgeprops = {'edgecolor': 'white', 'linewidth': 3}작은 조각 처리와 라벨 겹침 해결
작은 조각이 많으면 라벨이 서로 겹칠 수 있습니다. 범례를 사용하거나, figure 크기를 키우거나, 라벨 위치를 조정하는 방식으로 해결할 수 있습니다.
import matplotlib.pyplot as plt
# Data with several small slices
sizes = [30, 25, 15, 10, 8, 5, 4, 3]
labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
colors = plt.cm.Set3(range(len(sizes)))
fig, ax = plt.subplots(figsize=(10, 8))
wedges, texts, autotexts = ax.pie(sizes, colors=colors, autopct='%1.1f%%',
startangle=90, pctdistance=0.85)
# Remove labels from pie and use legend
for text in texts:
text.set_text('')
ax.legend(wedges, labels, title="Categories", loc="center left",
bbox_to_anchor=(1, 0, 0.5, 1))
ax.axis('equal')
ax.set_title('Distribution with Many Categories', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()또 다른 방법으로는, 차트에는 퍼센트만 표시하고 카테고리명은 범례로 빼서 시각적 혼잡을 줄일 수 있습니다.
여러 링을 가진 비례 도넛 차트 만들기
여러 레벨의 분해를 보여주는 복잡한 계층형 시각화를 만들 수 있습니다.
import matplotlib.pyplot as plt
import numpy as np
# Department budget data
departments = ['Engineering', 'Sales', 'Marketing', 'Operations']
dept_budgets = [400000, 300000, 200000, 100000]
# Team breakdown within departments
teams = ['Backend', 'Frontend', 'Mobile',
'Field Sales', 'Inside Sales',
'Digital', 'Content',
'Logistics', 'Support']
team_budgets = [200000, 150000, 50000,
180000, 120000,
120000, 80000,
60000, 40000]
fig, ax = plt.subplots(figsize=(12, 8))
# Outer ring (departments)
dept_colors = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12']
outer_pie = ax.pie(dept_budgets, labels=departments, colors=dept_colors,
autopct='%1.1f%%', radius=1.3, wedgeprops={'width': 0.35})
# Inner ring (teams)
team_colors = ['#c0392b', '#e74c3c', '#ec7063',
'#2980b9', '#3498db',
'#27ae60', '#2ecc71',
'#d68910', '#f39c12']
inner_pie = ax.pie(team_budgets, labels=teams, colors=team_colors,
autopct='%1.0f%%', radius=0.95,
wedgeprops={'width': 0.35}, labeldistance=0.7,
textprops={'fontsize': 9})
ax.axis('equal')
plt.title('Organizational Budget Breakdown\nDepartments and Teams',
fontsize=16, fontweight='bold', pad=20)
plt.tight_layout()
plt.show()이 예시는 바깥 링이 부서 예산, 안쪽 링이 각 부서에 대응되는 팀 예산을 보여주는 2단계 도넛 차트를 생성합니다.
FAQ
matplotlib에서 기본 파이 차트는 어떻게 만들나요?
plt.pie()에 값 리스트와(선택적으로) 라벨을 전달해 사용합니다. 타원이 아닌 원형으로 보이게 하려면 plt.axis('equal')을 포함하세요. 기본 문법은 plt.pie(sizes, labels=labels)이며, 마지막에 plt.show()로 차트를 표시합니다.
matplotlib 파이 차트에서 autopct 파라미터는 무엇을 하나요?
autopct는 각 조각에 퍼센트 값을 자동으로 표시합니다. 소수점 한 자리 퍼센트는 '%1.1f%%', 정수 퍼센트는 '%1.0f%%'를 사용합니다. 커스텀 함수를 전달하면 퍼센트와 실제 값(카운트)을 동시에 표시하는 등 더 유연한 표현이 가능합니다.
matplotlib에서 도넛 차트는 어떻게 만들나요?
wedgeprops에 width 값을 1보다 작게 지정해 도넛 차트를 만듭니다. 예를 들어 wedgeprops={'width': 0.4}는 반지름의 40% 두께 링을 만듭니다. plt.text()를 함께 사용하면 가운데 빈 공간에 라벨을 넣을 수 있습니다.
파이 차트에서 특정 조각을 분리(explode)하려면 어떻게 하나요?
explode 파라미터에 각 조각의 오프셋 값을 튜플로 전달합니다. 예를 들어 explode=(0.1, 0, 0, 0)는 첫 번째 조각을 반지름의 10%만큼 바깥으로 이동시키고 나머지는 그대로 둡니다. 값이 클수록 더 크게 분리됩니다.
막대 차트 대신 파이 차트를 써야 하는 경우는 언제인가요?
전체에서 부분을 보여주되 5개 이하 카테고리로 퍼센트 합이 100%가 되는 경우 파이 차트를 사용하세요. 카테고리 간 값 비교, 5개 초과 항목 표시, 정밀한 비교가 필요한 경우에는 막대 차트가 더 적합합니다. 막대 차트는 비슷한 크기의 구간을 비교하기 더 쉽습니다.
matplotlib 파이 차트 색상은 어떻게 커스터마이징하나요?
colors 파라미터에 색상 리스트를 전달합니다(색상명, hex 코드, RGB 튜플). 데이터 기반 색상에는 plt.cm.Set3 같은 컬러맵과 np.linspace() 조합으로 색상 배열을 만들 수 있습니다. 파이 차트에 인기 있는 컬러맵은 Set1, Set2, Set3, Pastel1 등이 있습니다.
파이 차트에서 조각 라벨 대신 범례를 추가하려면 어떻게 하나요?
plt.legend()를 라벨 리스트와 함께 호출하고, loc와 bbox_to_anchor로 위치를 조정합니다. 예: plt.legend(labels, loc='upper left', bbox_to_anchor=(1, 0, 0.5, 1))는 범례를 차트 오른쪽 바깥에 배치합니다. plt.tight_layout()을 사용하면 잘림을 방지할 수 있습니다.
결론
Matplotlib 파이 차트는 적절한 상황에서 비율 데이터를 시각화하는 강력한 방법입니다. 이 가이드에서는 기본 원형 차트부터 고급 중첩 도넛 시각화까지 전체 스펙트럼을 다뤘고, 라벨, 색상, 분리 조각, 퍼센트 표시, DataFrame 연동을 실전 예제로 설명했습니다. 파라미터 레퍼런스 표는 커스터마이징 옵션을 빠르게 찾아볼 수 있는 치트시트 역할을 하며, 예산 분석/설문 결과/시장 점유율 리포팅 같은 실무 예시는 이러한 기법을 실제 문제에 적용하는 방법을 보여줍니다.
파이 차트는 카테고리가 적고 비율이 명확할 때 가장 효과적이며, 세부 비교에는 막대 차트가 더 적합하다는 점을 기억하세요. 분석 과정에서 인터랙티브 탐색이 필요하다면 PyGWalker가 matplotlib로 프로덕션 시각화를 확정하기 전 빠른 프로토타이핑을 위한 코드 없는 대안을 제공합니다. “파이 vs 막대”를 언제 선택할지에 대한 설계 판단과 matplotlib 커스터마이징 기법을 함께 활용하면, 어떤 청중에게도 인사이트를 명확하고 설득력 있게 전달하는 시각화를 만들 수 있습니다.