본문 바로가기
🐍Python

[20210805] Matplotlib, Seaborn 라이브러리를 이용한 데이터 시각화

by 캔 2021. 8. 5.

Matplotlib

Matplotlib은 numpy, pandas를 이용하여 그래프를 그리는 라이브러리이다. 명령 프롬프트나 터미널에 'pip install matplotlib'을 입력하여 설치한다.

# Matplotlib
import matplotlib.pyplot as plt
import numpy as np

plt.rc('font', family='gulim')  # 한글 지원 폰트로 폰트를 변경

# 단일 그래프
data = np.arange(1, 100)  # arange(a, b) 메서드는 a부터 b까지의 수로 이뤄진 numpy 배열을 만든다.
plt.plot(data)
plt.show()

# 이중 그래프
data1 = np.arange(1, 51)
plt.plot(data1)
data2 = np.arange(51, 100)
plt.plot(data2)
plt.show()

# 여러 개의 plot을 그리는 방법
data = np.arange(1, 51)
fig, axes = plt.subplots(2, 3)
axes[0, 0].plot(data)
axes[0, 1].plot(data * data)
axes[0, 2].plot(data ** 3)
axes[1, 0].plot(data % 10)
axes[1, 1].plot(-data)
axes[1, 2].plot(data // 20)
plt.tight_layout()
plt.show()

# 주요 스타일
# 1. 제목(title)
plt.plot([1, 2, 3], [3, 6, 9])
plt.plot([1, 2, 3], [2, 4, 9])
plt.title('이중 그래프', fontsize=20)
plt.show()

# 2. x, y축 레이블(label) 설정
plt.plot([1, 2, 3], [3, 6, 9])
plt.plot([1, 2, 3], [2, 4, 9])
plt.title('Label 설정 예제입니다.', fontsize=20)
plt.xlabel('x축', fontsize=20)  # x축 Label 설정
plt.ylabel('y축', fontsize=20)  # y축 Label 설정
plt.show()

# 3. x, y축 눈금(tick) 설정
plt.plot(np.arange(10), np.arange(10) * 2)
plt.plot(np.arange(10), np.arange(10) ** 2)
plt.title("X, Y틱을 조정합니다.", fontsize=20)
plt.xlabel('x축', fontsize=20)
plt.ylabel('y축', fontsize=20)
plt.xticks(rotation=90)  # x축 눈금 설정
plt.yticks(rotation=30)  # y축 눈금 설정
plt.show()

# 4. 범례(legend) 설정
plt.plot(np.arange(10), np.arange(10) * 2)
plt.plot(np.arange(10), np.arange(10) ** 2)
plt.plot(np.arange(10), np.log(np.arange(10)))
plt.title("범례 설정 예제", fontsize=20)
plt.xlabel("x축", fontsize=20)
plt.ylabel("y축", fontsize=20)
plt.xticks(rotation=90)
plt.yticks(rotation=30)
plt.legend(['10 * 2', '10 ** 2', 'log'], fontsize=15)  # 범례 설정
plt.show()

# 5. x축, y축의 한곗값(limit) 설정
plt.plot(np.arange(10), np.arange(10) * 2)
plt.plot(np.arange(10), np.arange(10) ** 2)
plt.plot(np.arange(10), np.log(np.arange(10)))
plt.title("범례 설정 예제", fontsize=20)
plt.xlabel("x축", fontsize=20)
plt.ylabel("y축", fontsize=20)
plt.xticks(rotation=90)
plt.yticks(rotation=30)
plt.legend(['10 * 2', '10 ** 2', 'log'], fontsize=15)
plt.xlim(0, 5)  # x축 한곗값 설정
plt.ylim(0.5, 10)  # y축 한곗값 설정
plt.show()

# 6. 스타일 세부 설정 - 마커(marker)
plt.plot(np.arange(10), np.arange(10) * 2, marker='o', markersize=5)
plt.plot(np.arange(10), np.arange(10) * 2 - 10, marker='v', markersize=10)
plt.plot(np.arange(10), np.arange(10) * 2 - 20, marker='+', markersize=15)
plt.plot(np.arange(10), np.arange(10) * 2 - 30, marker='*', markersize=20)
plt.show()

# 7. 스타일 세부 설정 - 라인(linestyle: 라인 스타일, color: 라인색, alpha: 투명도)
plt.plot(np.arange(10), np.arange(10) * 2, marker='o', linestyle='', color='b')
plt.plot(np.arange(10), np.arange(10) * 2 - 10, marker='o', linestyle='-', color='b', alpha=0.1)
plt.plot(np.arange(10), np.arange(10) * 2 - 20, marker='v', linestyle='--', color='c', alpha=0.3)
plt.plot(np.arange(10), np.arange(10) * 2 - 30, marker='+', linestyle='-.', color='y', alpha=0.5)
plt.plot(np.arange(10), np.arange(10) * 2 - 40, marker='*', linestyle=':', color='r', alpha=0.7)
plt.show()

# 8. 격자(grid) 설정
plt.plot(np.arange(10), np.arange(10) * 2)
plt.plot(np.arange(10), np.arange(10) * 2 - 10)
plt.grid()  # 격자 표시
plt.show()

# 9. 산점도(scatter plot): scatter()
# x, y, colors, area 설정하기
np.random.rand(50)
np.arange(50)

x = np.random.rand(50)
y = np.random.rand(50)
colors = np.arange(50)
area = x * y * 1000
plt.scatter(x, y, s=area, c=colors)
plt.show()

# cmap: 컬러 지정, alpha: 투명도 0~1 사이의 값 지정 0에 가까울수록 투명
np.random.rand(50)
plt.figure(figsize=(12, 6))
x = np.random.rand(50)
y = np.random.rand(50)
colors = np.arange(50)
area = x * y * 1000
plt.subplot(131)
plt.scatter(x, y, s=area, cmap='blue', alpha=0.1)
plt.title('alpha=0.1')
plt.subplot(132)
plt.scatter(x, y, s=area, cmap='blue', alpha=0.5)
plt.title('alpha=0.5')
plt.subplot(133)
plt.scatter(x, y, s=area, cmap='blue', alpha=1.0)
plt.title('alpha=1.0')
plt.show()

# 10. 막대 그래프(bar plot): bar()
# 기본 막대 그래프
x = ['Math', 'Programming', 'Data Science', 'Art', 'English', 'Physics']
y = [66, 80, 60, 50, 80, 20]
plt.bar(x, y, align='center', alpha=0.7, color='red')  # x축으로 그리기
plt.xticks(x)
plt.barh(x, y, align='center', alpha=0.7, color='green')  # y축으로 그리기
plt.yticks(x)
plt.xlabel('Number of Students')
plt.title('Subjects')
plt.show()

# 비교 막대 그래프 그리기, x축
x_label = ['Math', 'Programming', 'Data Science', 'Art', 'English', 'Physics']
x = np.arange(len(x_label))
y_1 = [66, 80, 60, 50, 80, 20]
y_2 = [55, 90, 40, 60, 70, 10]
width = 0.35  # 넓이 지정
fig, axes = plt.subplots()  # subplot 생성
axes.bar(x - width / 2, y_1, width, align='center', alpha=0.5)  # 넓이 설정
axes.bar(x + width / 2, y_2, width, align='center', alpha=0.8)  # 넓이 설정
plt.xticks(x)  # x축 눈금 설정
axes.set_xticklabels(x_label)
plt.ylabel('Numbers of Students')
plt.title('Subjects')
plt.legend(['John', 'Peter'])
plt.show()

# 11. 꺾은선 그래프(line plot): plot(), 기본 그래프임
# 기본 꺾은선 그래프
x = np.arange(0, 10, 0.1)
y = np.sin(x)
plt.plot(x, y)
plt.xlabel('x value', fontsize=15)
plt.ylabel('y value', fontsize=15)
plt.title('Sine graph', fontsize=18)
plt.grid()
plt.show()

# 2개 이상의 그래프 그리기
# marker: 마커 옵션
# linestyle: 라인 스타일 변경 옵션
x = np.arange(0, 10, 0.1)
y_1 = np.sin(x)
y_2 = np.cos(x)

plt.plot(x, y_1, label='sin', color='blue', alpha=0.3) # 일반 선그래프
plt.plot(x, y_2, label='cos', color='red', alpha=0.7) # 일반 선그래프
plt.plot(x, y_1, label='sin', color='blue', alpha=0.3, marker='o') # 마커 옵션 적용
plt.plot(x, y_2, label='cos', color='red', alpha=0.7, marker='+') # 마커 옵션 적용
plt.plot(x, y_1, label='sin', color='blue', alpha=0.3, linestyle=':')
plt.plot(x, y_2, label='cos', color='red', alpha=0.7, linestyle='-.')
plt.xlabel('x value', fontsize=15)
plt.ylabel('y value', fontsize=15)
plt.title('sin and cos graph', fontsize=18)
plt.grid()
plt.legend()
plt.show()

# 12. 영역 그래프(Areaplot)
x = np.arange(1, 21)
y = np.random.randint(low=5, high=10, size=20)

# fill_between()으로 색칠하기
plt.fill_between(x,y,color='green', alpha=0.6)

# 경계선을 굵게, area는 옅게 그리기
plt.fill_between(x, y, color="green", alpha=0.3)  # area
plt.plot(x, y, color="green", alpha=0.8)  # 경계선
plt.show()

# 여러 개의 그래프를 겹쳐서 표현
x = np.arange(1, 10, 0.05)
y_1 = np.cos(x) + 1
y_2 = np.sin(x) + 1
y_3 = y_1 * y_2 / np.pi
plt.fill_between(x, y_1, color="green", alpha=0.1)
plt.fill_between(x, y_2, color="blue", alpha=0.2)
plt.fill_between(x, y_3, color="red", alpha=0.3)
plt.show()

# 13. 히스토그램
N = 100000
bins = 30

x = np.random.randn(N)
y = .4 * x + np.random.randn(100000) + 5
plt.hist(x, bins=bins)
plt.show()

# 다중 히스토그램
N = 100000
bins = 30
x = np.random.randn(N)
y = .4 * x + np.random.randn(100000) + 5
fig, axs = plt.subplots(1, 2, sharey=True, tight_layout=True)
axs[0].hist(x, bins=bins, density=True)  # y축에 Density 표기
axs[1].hist(y, bins=bins, density=True)
plt.show()

# 14. 원 그래프(pie chart)
# 파이 차트 옵션
labels = ['Samsung', 'Huawei', 'Apple', 'Xiaomi', 'Oppo', 'Etc']
sizes = [20.4, 15.8, 10.5, 9, 7.6, 36.7]
explode = (0.3, 0, 0, 0, 0, 0)
patches, texts, autotexts = plt.pie(
    sizes,
    explode=explode,
    labels=labels,
    autopct='%1.1f%%',
    shadow=True,
    startangle=90)
plt.title('SmartPhone pie', fontsize=15)
for t in texts:
    t.set_fontsize(12)
    t.set_color('gray')
for t in autotexts:
    t.set_color("white")
    t.set_fontsize(18)
plt.show()

# 15. 박스 플롯(box plot)
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data = np.concatenate((spread, center, flier_high, flier_low))
plt.boxplot(data)
plt.tight_layout()
plt.show()

# 다중 박스 플롯
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data = np.concatenate((spread, center, flier_high, flier_low))
spread = np.random.rand(50) * 100
center = np.ones(25) * 40
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
d2 = np.concatenate((spread, center, flier_high, flier_low))
data = [data, d2]
plt.boxplot(data)
plt.show()
plt.title('Horizontal Box plot', fontsize=15)
plt.boxplot(data, vert=False)  # y축으로 출력
plt.show()

# 아웃라이어(outlier, 이상치) 마커 심볼과 컬러 변경
outlier_marker = dict(markerfacecolor='r', marker='D')
plt.title('Changed Outlier Symbols', fontsize=15)
plt.boxplot(data, flierprops=outlier_marker)
plt.show()

 

Seaborn

Seaborn은 matplotlib의 상위 호환 데이터 시각화 라이브러리이다. 명령 프롬프트에서 'pip install seaborn'를 입력하여 설치할 수 있다.

# Seaborn
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

plt.rc('font', family='gulim')  #한글 지원 폰트로 폰트 변경

# seaborn 라이브러리의 기본 제공 데이터인 titanic과 tips를 로드
titanic = sns.load_dataset('titanic')
tips = sns.load_dataset('tips')
sns.set(style='darkgrid')

# 1. countplot
# X축 출력
sns.countplot(x="class", hue="who", data=titanic)
plt.show()

# Y축 출력
sns.countplot(y="class", hue="who", data=titanic)
plt.show()

# 색상 팔레트 설정
sns.countplot(x="class", hue="who", palette='Paired', data=titanic)
plt.show()

# 2. distplot: matplotlib의 hist, seaborn의 kdeplot을 통합한 그래프
x = np.random.randn(100)
sns.distplot(x)
plt.show()

# 2.1 데이터가 Series일 경우
x = np.random.randn(100)
x = pd.Series(x, name="x variable")
sns.distplot(x)
plt.show()

# 2.2 rugplot: X축 위에 작은 선분(rug)으로 나타내어 데이터들의 위치 분포를 보여준다.
x = np.random.randn(100)
sns.distplot(x, rug=True, hist=False)
plt.show()

# 2.3 kde (Kernel density): 히스토그램보다 부드러운 분포 곡선을 보여준다.
x = np.random.randn(100)
sns.distplot(x, rug=False, hist=False, kde=True)
plt.show()

# 2.4 가로로 표현
x = np.random.randn(100)
sns.distplot(x, vertical=True)
plt.show()

# 2.5 컬러 바꾸기
x = np.random.randn(100)
sns.distplot(x, color="r")
plt.show()

# 3.히트맵(heatmap): 색상으로 표현할 수 있는 다양한 정보를 일정한 이미지 위에 열 분포 형태의 비주얼 그래픽으로 출력
# 3.1 기본 히트맵
uniform_data = np.random.rand(10, 12)
sns.heatmap(uniform_data, annot=True)
plt.show()

# 3.2 피벗테이블(pivot table)을 활용하여 그리기
pivot = tips.pivot_table(index='day', columns='size', values='tip')
sns.heatmap(pivot, annot=True)
plt.show()

# 3.3 상관관계(correlation)를 시각화. corr() 함수 사용
sns.heatmap(titanic.corr(), annot=True, cmap='YlGnBu')
plt.show()

# 4.pairplot: 격자(grid) 형태로 각 집합의 조합에 대해 히스토그램과 분포도를 그림
# 4.1 기본 pairplot 그리기
sns.pairplot(tips)
plt.show()

# 4.2 hue 옵션으로 특성 구분
sns.pairplot(tips, hue='size')
plt.show()

# 4.3 컬러 팔레트 적용
sns.pairplot(tips, hue='size', palette="rainbow")
plt.show()

# 4.4 사이즈 적용
sns.pairplot(tips, hue='size', palette="rainbow", height=5, )
plt.show()

# 5. violinplot: 바이올린 처럼 생긴 플롯. 칼럼에 대한 데이터의 비교 분포도를 확인할 수 있다.
# 5.1 기본 violinplot
sns.violinplot(x=tips["total_bill"])
plt.show()

# 5.2 비교 분포 확인: x, y축 지정으로 비교 분포를 볼 수 있다.
sns.violinplot(x="day", y="total_bill", data=tips)
plt.show()

# 5.3 가로 출력
sns.violinplot(y="day", x="total_bill", data=tips)
plt.show()

# 5.4 hue 옵션으로 분포 비교: 단일 칼럼에 대한 바이올린 모양의 비교
sns.violinplot(x="day", y="total_bill", hue="smoker", data=tips, palette="muted")
plt.show()

# 5.5 split 옵션으로 바이올린을 합쳐서 볼 수 있다.
sns.violinplot(x="day", y="total_bill", hue="smoker", data=tips, palette="muted", split=True)
plt.show()

# 6. lmplot: 칼럼 간의 선형 관계를 확인하기 용이한 차트
# 6.1. 기본 lmplot
sns.lmplot(x="total_bill", y="tip", height=8, data=tips)
plt.show()

# 6.2 hue 옵션으로 다중 선형관계 그리기
sns.lmplot(x='total_bill', y='tip', hue='smoker', height=8, data=tips)
plt.show()

# 6.3 col 옵션, 그래프를 별도로 그려보기
sns.lmplot(x='total_bill', y='tip', hue='smoker', col='day', col_wrap=2, height=8, data=tips)
plt.show()

# 7. relplot: 두 칼럼 간 상관관계를 보여주지만, lmplot처럼 선형관계를 따로 그려주지는 않는다.
# 7.1 기본 relplot
sns.relplot(x='total_bill', y='tip', hue='day', data=tips)
plt.show()

# 7.2 col 옵션으로 그래프 분활
sns.relplot(x='total_bill', y='tip', hue='day', col='time', data=tips)
plt.show()

# 7.3 로우와 칼럼에 표기할 데이터. 칼럼 선택
sns.relplot(x='total_bill', y='tip', hue='day', row='sex', col='time', data=tips)
plt.show()

# 7.4 컬러 팔레트 적용
sns.relplot(x='total_bill', y='tip', hue='day', row='sex', col='time', palette='CMRmap_r', data=tips)
plt.show()

# 8. joinplot: scatter(산점도), histogram(분포)을 동시에 그려준다. 숫자형 데이터만 가능
# 8.1 기본 joinplot 그리기
sns.jointplot(x="total_bill", y='tip', height=8, data=tips)
plt.show()

# 8.2 선형관계를 표현하는 회귀선(regression line) 그리기
sns.jointplot(x="total_bill", y='tip', height=8, data=tips, kind="reg")
plt.show()

# 8.3 hex 밀도 보기
sns.jointplot(x="total_bill", y='tip', height=8, data=tips, kind="hex")
plt.show()

# 8.4 등고선 모양으로 밀집도 확인: kde 옵션으로 데이터의 밀집도를 보다 부드러운 선으로 확인할 수 있다.
iris = sns.load_dataset('iris')
sns.jointplot("sepal_width", "petal_length", height=8, data=iris, kind="kde", color="g")
plt.show()