5.3.3 막대 그래프

① 막대 그래프 함수 bar()와 barh()

막대 그래프는 이산형 자료의 값을 직사각형 막대를 사용하여 데이터를 시각화하는 방법이다. 함수 bar()를 사용하여 막대 그래프를 그려보자.

다음 코드에서 점수를 나타내는 막대의 세로 높이를 point에, 대응되는 학생의 해당 학생 이름을 name에 저장한다. 함수 bar(name, ...)의 첫 인자는 x축에 표시되는 학생 이름인 name이다. 인자 color로 막대의 색상을 지정할 수 있다. 다음 결과에서 보듯이 함수 bar는 세로 막대 방향으로 그려진다.

import matplotlib.pyplot as plt

point = [99, 65, 79, 80, 90]
name = ["영희", "철수", "동수", "미현", "현수"]

plt.bar(name, point, color=["blue", "chartreuse", "purple", "grey", "orange"])
plt.title('데이터분석 점수');

함수 barh()로 막대 그래프를 가로로 그려보자. 인자 height로 막대의 너비를 조절할 수 있다.

import matplotlib.pyplot as plt

point = [99, 65, 79, 80, 90]
name = ["영희", "철수", "동수", "미현", "현수"]

plt.barh(name, point, height=.6, color=["blue", "chartreuse", "purple", "grey", "orange"])
plt.title('데이터분석 점수')
plt.xlabel('점수')
plt.ylabel('이름');

수직 막대그래프는 범주별 랭킹을 직관적으로 보여주며, 가로형(barh) 막대그래프는 항목 이름이 길거나 순위를 강조하여 텍스트 겹침을 방지하고 싶을 때 매우 유용합니다. barh를 쓸 때는 X축과 Y축의 라벨 의미가 서로 직교로 바뀌게 됨에 주의해야 합니다.

② 내장 데이터 LifeCycleSavings의 막대 그래프

내장 데이터 LifeCycleSavings는 “국가별 생애주기 저축 데이터”이다. 5개의 변수와 50개의 관측 값이 있다.

from pydataset import data

lcs = data('LifeCycleSavings')
lcs.info()
lcs.describe()

내장 데이터 LifeCycleSavings의 첫 5개의 관측 값은 다음과 같다.

lcs.iloc[:5]

데이터 LifeCycleSavings의 상위 5행과 두 번째 열 pop15로 구성된 데이터프레임을 객체 df에 저장한다.

df = lcs[:5][['pop15']]
print(df)

다음은 “15세 미만의 인구비율”을 나타내는 열 pop15 값을 plt.bar()로 그린 결과이다.

plt.bar(df.index, df.pop15)
plt.title("국가별 15세미만 인구비율")
plt.xlabel("국가")
plt.ylabel("15세미만 인구비율(%)");

③ 메소드 value_counts()를 활용한 막대 그래프

다음은 이미 살펴본 내장 데이터 mtcars 정보이다.

from pydataset import data

mtc = data('mtcars')
mtc.info()

두 번째 열 cyl은 자동차의 실린더(기통) 수이다. 자료 mtcars에서 실린더 수 빈도를 알기 위해 mtc.cyl.value_counts()를 사용한다.

mtc_cyl = mtc.cyl.value_counts()
# 5.3.3 14
# 5.3.3 11
# 5.3.3 7
# 5.3.3 Name: cyl, dtype: int64

이는 8기통이 14대, 4기통이 11대, 6기통이 7대임을 나타낸다. 기본적으로 빈도 수가 많은 것이 먼저 표시된다.

이 분포를 사용해 간단히 다음 막대 그래프를 그릴 수 있다.

plt.bar(mtc_cyl.index, mtc_cyl)
plt.title("자동차 실린더(기통) 분포")
plt.xlabel("실린더 수")
plt.ylabel("자동차 수");

④ 패키지 seaborn의 함수 sns.countplot()으로 그리는 막대 그래프

[실전 꿀팁]: 막대 그래프 2대장 (barplot vs countplot)

  • countplot: 분류 항복별 데이터 개수(빈도)를 셉니다. (예: “기어가 4개인 자동차는 총 몇 대지?”)
  • barplot: 구분에 따른 특정 데이터의 평균값을 막대 높이로 표시합니다. (다양한 집단 간의 대표값을 보여줄 때 매우 강력합니다.)

이번에는 데이터 시각화 패키지 seaborn을 사용해 보자. seaborn은 내부적으로 matplotlib을 사용하며 보다 간단하고 다양한 데이터를 시각화 할 수 있는 라이브러리이다.

패키지 seaborn의 함수 sns.countplot(data, x='gear', ...)는 데이터프레임 mtc의 변수 gear의 빈도 수를 나타내는 막대 그래프를 그려준다.

다음으로 데이터프레임 mtc의 변수 gear의 빈도 수의 막대 그래프를 그린다.

import seaborn as sns
sns.countplot(data=mtc, x='gear');

함수 sns.countplot()의 반환 객체는 Axes라는 객체이며 이를 활용하면 빈도 수를 알 수 있고, 이 값을 막대 그래프에 표시할 수 있다. 이 빈도 수를 막대 그래프에 직접 표시해 보자.

다음 코드와 같이 반환 받은 Axes를 변수 axax.patches로 그래프의 각 막대(patch)에 대해 반복문을 실행한다. 반복문에서 p.get_height()로 현재 막대의 높이, 즉 빈도 수를 가져오고 ax.text(x, y, s=int(height), ...)로 빈도수 값(height)을 막대 위 위치 (x, y)에 표시한다. 다음 막대 그래프의 결과로 변수 gear는 자동차의 기어 수는 3, 4, 5가 있으며 각각 15대, 12대, 5대의 빈도임을 알 수 있다.

import seaborn as sns
ax = sns.countplot(data=mtc, x='gear', order=mtc.gear.value_counts().index)

for p in ax.patches:
    height = p.get_height() # 빈도 수
    ax.text(x = (p.get_x() + p.get_width() / 2.), y = (height + .2),
            s = int(height), ha = 'center', size = 12, color = 'blue')

ax.set_ylim(0, 17) # y축의 범위를 0부터 17까지로 설정
plt.show()

객체 Axes의 메소드 text(x, y, s, ...)는 위치 (x, y)에 글자 s를 표시하는 메소드이다.

  • x = (p.get_x() + p.get_width() / 2.): 텍스트를 막대의 중앙에 위치
  • y = (height + .2): 텍스트를 막대의 바로 위에 위치
  • s = int(height): 텍스트 내용은 막대의 높이 (빈도 수)로 설정
  • ha = 'center': 텍스트를 중앙 정렬
  • size = 12: 텍스트 크기를 12로 설정
  • color = 'blue': 텍스트 색상을 파란색으로 설정
서브목차