Matplotlib 막대 그래프: plt.bar()와 plt.barh() 완전 가이드
Updated on
막대 그래프는 카테고리 간 수량을 비교하는 가장 일반적인 방법입니다. 분기별 매출, 학생별 점수, 상태별 카운트 -- 막대 그래프는 이러한 비교를 즉시 읽을 수 있게 만듭니다. 하지만 Matplotlib에서 효과적인 막대 그래프를 만들려면 단순한 plt.bar() 호출 이상이 필요합니다. 그룹화된 비교, 누적 구성, 긴 레이블을 위한 수평 레이아웃, 그래프를 자명하게 만드는 적절한 주석을 처리해야 합니다.
이 가이드는 기본 수직 막대부터 고급 그룹화 및 누적 구성까지 Matplotlib에서 필요한 모든 막대 그래프 패턴을 다룹니다.
기본 수직 막대 그래프
import matplotlib.pyplot as plt
categories = ['Python', 'JavaScript', 'Java', 'C++', 'Go']
values = [35, 28, 22, 15, 12]
plt.figure(figsize=(8, 5))
plt.bar(categories, values, color='steelblue', edgecolor='black', linewidth=0.5)
plt.xlabel('언어')
plt.ylabel('인기 점수')
plt.title('프로그래밍 언어 인기도')
plt.show()plt.barh()를 사용한 수평 막대 그래프
카테고리 레이블이 길거나 카테고리가 많을 때 수평 막대를 사용합니다:
import matplotlib.pyplot as plt
frameworks = ['React', 'Vue.js', 'Angular', 'Svelte', 'Next.js',
'Django', 'Flask', 'FastAPI', 'Express', 'Rails']
stars = [220, 207, 95, 78, 124, 78, 67, 74, 64, 55]
plt.figure(figsize=(10, 6))
plt.barh(frameworks, stars, color='#3498db', edgecolor='white')
plt.xlabel('GitHub 스타 (천)')
plt.title('GitHub 스타 기준 프레임워크 인기도')
plt.gca().invert_yaxis() # 가장 높은 것을 위로
plt.tight_layout()
plt.show()색상 사용자 정의
import matplotlib.pyplot as plt
categories = ['Q1', 'Q2', 'Q3', 'Q4']
revenue = [120, 150, 180, 200]
# 막대마다 다른 색상
colors = ['#e74c3c', '#f39c12', '#2ecc71', '#3498db']
plt.figure(figsize=(8, 5))
bars = plt.bar(categories, revenue, color=colors, edgecolor='black', linewidth=0.5)
plt.ylabel('매출 ($K)')
plt.title('분기별 매출')
plt.show()막대에 값 레이블 추가
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 32]
plt.figure(figsize=(8, 5))
bars = plt.bar(categories, values, color='steelblue')
# 각 막대 위에 값 레이블 추가
for bar, val in zip(bars, values):
plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 1,
str(val), ha='center', va='bottom', fontsize=11)
plt.ylabel('값')
plt.title('값 레이블이 있는 막대 그래프')
plt.show()그룹화 막대 그래프
여러 시리즈를 나란히 비교:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Q1', 'Q2', 'Q3', 'Q4']
product_a = [20, 35, 30, 35]
product_b = [25, 32, 34, 20]
product_c = [15, 20, 25, 30]
x = np.arange(len(categories))
width = 0.25
plt.figure(figsize=(10, 6))
plt.bar(x - width, product_a, width, label='제품 A', color='#e74c3c')
plt.bar(x, product_b, width, label='제품 B', color='#3498db')
plt.bar(x + width, product_c, width, label='제품 C', color='#2ecc71')
plt.xlabel('분기')
plt.ylabel('매출 ($K)')
plt.title('제품별 분기 매출')
plt.xticks(x, categories)
plt.legend()
plt.tight_layout()
plt.show()누적 막대 그래프
각 카테고리의 구성을 표시:
import matplotlib.pyplot as plt
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
mobile = [30, 35, 40, 45]
desktop = [50, 45, 35, 30]
tablet = [20, 20, 25, 25]
plt.figure(figsize=(8, 6))
plt.bar(quarters, mobile, label='모바일', color='#3498db')
plt.bar(quarters, desktop, bottom=mobile, label='데스크톱', color='#e74c3c')
# 세 번째 누적을 위해 누적 bottom 계산
import numpy as np
bottom_2 = np.array(mobile) + np.array(desktop)
plt.bar(quarters, tablet, bottom=bottom_2, label='태블릿', color='#2ecc71')
plt.ylabel('트래픽 (%)')
plt.title('분기별 트래픽 소스')
plt.legend()
plt.show()오차 막대
import matplotlib.pyplot as plt
import numpy as np
categories = ['대조군', '처리 A', '처리 B', '처리 C']
means = [10.2, 15.8, 14.3, 18.1]
errors = [1.2, 2.1, 1.8, 2.5]
plt.figure(figsize=(8, 5))
plt.bar(categories, means, yerr=errors, capsize=5,
color='steelblue', edgecolor='black', linewidth=0.5)
plt.ylabel('응답 값')
plt.title('오차 막대가 있는 처리 효과')
plt.show()plt.bar() 매개변수 참조
| 매개변수 | 유형 | 설명 |
|---|---|---|
x | 배열형 | 막대 위치 (카테고리) |
height | 배열형 | 막대 높이 (값) |
width | float | 막대 너비 (기본값 0.8) |
bottom | 배열형 | 막대 기저의 Y 좌표 (누적용) |
color | 색상 또는 배열 | 막대 채우기 색상 |
edgecolor | 색상 | 막대 테두리 색상 |
linewidth | float | 테두리 선 너비 |
yerr / xerr | 배열형 | 오차 막대 크기 |
capsize | float | 오차 막대 캡 너비 |
align | str | 막대 정렬 ('center' 또는 'edge') |
label | str | 범례 레이블 |
alpha | float | 투명도 (0-1) |
PyGWalker를 활용한 인터랙티브 막대 그래프
탐색적 데이터 분석을 위해 PyGWalker (opens in a new tab)는 Jupyter에서 DataFrame의 열을 드래그 앤 드롭하여 인터랙티브 막대 그래프를 만들 수 있게 합니다:
import pandas as pd
import pygwalker as pyg
df = pd.DataFrame({
'Quarter': ['Q1', 'Q2', 'Q3', 'Q4'] * 3,
'Product': ['A'] * 4 + ['B'] * 4 + ['C'] * 4,
'Sales': [20, 35, 30, 35, 25, 32, 34, 20, 15, 20, 25, 30]
})
walker = pyg.walk(df)FAQ
Matplotlib에서 막대 그래프를 어떻게 만드나요?
수직 막대에는 plt.bar(카테고리, 값)을, 수평 막대에는 plt.barh(카테고리, 값)을 사용합니다. 카테고리와 해당 값의 리스트 또는 배열을 전달합니다. plt.xlabel(), plt.ylabel(), plt.title()로 레이블을 추가합니다.
그룹화 막대 그래프를 어떻게 만드나요?
x 위치에 np.arange()를 사용하고 각 그룹을 막대 너비만큼 오프셋합니다. plt.bar()를 이동된 x 위치로 여러 번 호출합니다: plt.bar(x - width, data1, width), plt.bar(x, data2, width) 등. plt.xticks(x, 카테고리)로 눈금 레이블을 설정합니다.
막대 위에 값 레이블을 어떻게 추가하나요?
막대 객체를 반복하며 plt.text()를 사용합니다. 각 막대에 대해 bar.get_x() + bar.get_width() / 2로 중앙 x 위치를, bar.get_height()로 y 위치를 계산합니다. 수평 정렬에는 ha='center'를 사용합니다.
누적 막대 그래프를 어떻게 만드나요?
연속적인 plt.bar() 호출에서 bottom 매개변수를 사용합니다. 첫 번째 호출에는 bottom이 없습니다. 두 번째 호출은 첫 번째 데이터셋을 bottom으로 사용합니다. 세 번째 누적에는 처음 두 데이터셋의 합을 bottom으로 사용합니다.
수평 vs 수직 막대 그래프를 언제 사용해야 하나요?
카테고리 레이블이 길거나, 카테고리가 많거나 (8-10개 이상), 기준선과 비교할 때 수평 막대 (plt.barh())를 사용합니다. 시계열 카테고리 (월, 분기)나 짧은 레이블의 적은 카테고리에는 수직 막대 (plt.bar())를 사용합니다.
결론
Matplotlib의 plt.bar()와 plt.barh()는 모든 막대 그래프 요구를 충족합니다: 기본 비교, 그룹화된 다중 시리즈, 누적 구성, 주석이 달린 프레젠테이션. 그룹화 막대에는 np.arange()로 x 위치를 오프셋합니다. 누적 막대에는 bottom 매개변수를 사용합니다. 항상 명확성을 위해 값 레이블을 추가하고 레이블이 길 때는 수평 레이아웃을 선택하세요.