앞에 데이터 시각화 첫 장에서 데이터 시각화를 하는 방법을 배웠다.
이번에는 자주 사용되는 그래프를 직접 그려보며 연습해보자.
Seaborn의 load_dataset()
메서드를 이용하면 API를 통해 손쉽게 유명한 예제 데이터를 다운로드 할 수 있다.
참고 https://github.com/mwaskom/seaborn-data 여기의 repo 데이터는 모두 csv 파일로 되어있어 연습용으로 좋다.
메서드를 실행하면 home directory에 자동으로 seaborn-data라는 폴더가 생성되어 다운로드한 데이터가 내부에 저장된다.
import pandas as pd
import seaborn as sns
tips = sns.load_dataset("tips")
tips.csv, https://github.com/mwaskom/seaborn-data/blob/master/tips.csv
Pandas의 Dataframe을 이용해서 데이터가 어떻게 구성되어 있는지 확인해보자
df = pd.DataFrame(tips)
df.head()
df.shape()
df.describe()
df.info()
이 데이터에는 결측값이 없어 결측값 처리가 필요하지 않다.
데이터 변수들 중에서 ses
, smoker
, day
, time
이 범주(category)형 데이터고, tips
, total_bill
, size
는 수치형 데이터이다. 하지만 size
는 테이블 인원을 의미하기 때문에 범주형 데이터로 봐야 한다.
범주형 변수 카테고리별 개수 알아보기
print(df['sex'].value_counts())
print("===========================")
print(df['time'].value_counts())
print("===========================")
print(df['smoker'].value_counts())
print("===========================")
print(df['day'].value_counts())
print("===========================")
print(df['size'].value_counts())
print("===========================")
데이터가 준비되었으니 그래프를 그려보자
위에서 데이터는 범주형 변수와 수치형 변수가 있다는 것을 확인했다.
변수 데이터를 시각화할 때 데이터 종류에 따라 사용하는 그래프가 달라진다.
이제 범주형, 수치형 순서대로 총 4개의 그래프를 살펴보자.
범주형 데이터는 주로 막대그래프를 사용하여 수치를 요약한다. 일반적으로 가로, 세로, 누적, 그룹화된 막대그래프를 사용한다.
tips 데이터에서 범주형 변수는 ses
, smoker
, day
, time
, 'size'이다.
matplotlib에 데이터를 인자로 넣기 위해선 pandas 데이터를 바로 이용할 수는 없다. 데이터를 x에 series 또는 list, y에 list 형태로 각각 나눠줘야 한다.
df.head()
tip 칼럼을 성별에 대한 평균으로 나타내본다.
pandas의 groupby 메서드를 활용한다.
grouped = df['tip'].groupby(df['sex'])
df['tip']
컬럼을 groupby()
한다는 뜻으로, groupby()
의 인자는 sex를 넣어주었다. 이렇게 하면 각 성별 그룹에 대한 정보(총합, 평균, 데이터 량 등)가 grouped 객체에 저장된다.
grouped.mean() # 성별에 따른 팁의 평균
grouped.size() # 성별에 따른 데이터 량
성별에 따른 팁 액수의 평균을 막대그래프로 나타내보자
import numpy as np
sex = dict(grouped.mean()) # 평균 데이터를 딕셔너리 형태로 바꾼다
sex
x = list(sex.keys())
x
y = list(sex.values())
y
처음 설명한 것처럼 x, y를 list로 데이터를 변경해준다.
import matplotlib.pyplot as plt
plt.bar(x = x, height = y)
plt.ylabel('tip[$]')
plt.title('Tip by Sex')
seaborn을 이용하면 더 쉽게 나타낼 수 있다.
sns.barplot(data=df, x='sex', y='tip')
sns.barplot의 인자로 df를 넣고 원하는 컬럼을 지정해 주면, 성별에 대한 tip을 볼 수 있다.
Matplot과 함꼐 사용하여 figsize, title을 정하는 등 그래프에 다양한 옵션을 넣을 수도 있다.
plt.figure(figsize=(10,6)) # 도화지 사이즈를 정한다
sns.barplot(data=df, x='sex', y='tip')
plt.ylim(0,4) # y값의 범위를 정한다
plt.title('Tip by Sex') # 그래프 제목
아래는 요일에 따른 tips의 그래프이다.
plt,figure(figsize=(10,6))
sns.barplot(data=df, x='day', y='tip')
plt.ylim(0,4)
plt.title('Tip by day')
Subplot을 활용할 수도 있고, 범주형 그래프를 나타내기에 좋은 violin plot을 사용할 수도 있다.
palette 옵션을 사용해 더 이쁜 색상을 사용
할 수도 있다.
fig = plt.figure(figsize=(10,7))
ax1 = fig.add_subplot(2,2,1)
sns.barplot(data=df, x='day', y='tip', palette='ch:.25")
ax2 = fig.add_subplot(2,2,2)
sns.barplot(data=df, x='sex', y='tip')
ax3 = fig.add_subplot(2,2,4)
sns.violinplot(data=df, x='sex', y='tip')
ax4 = fig.add_subplot(2,2,3)
sns.violinplot(data=df, x='day', y='tip', palette='ch:.25")
catplot을 사용하여 나타낼 수도 있다.
sns.catplot(x='day', y='tip', jitter=False, data=tips)
수치형 데이터를 나타내가 가장 좋은 그래프는 산점도 혹은 선 그래프이다.
전체 음식 가격(total_bill)에 따른 tip
데이터를 시각화하며 산점도와 선 그래프를 배워보자.
hue인자에 'day'를 주어 요일(day)에 따른 tip과 total_bill의 관계를 시각화 해보자
sns.scatterplot(data=df, x='total_bill', y='tip', palette="ch:r=-.2,d=.3_r")
sns.scatterplot(data=df, x='total_bill', y='tip', hue='day')
plot의 기본은 선 그래프이다.
tips 예제로는 선 그래프 설명어 어려워, numpy를 이용하여 데이터를 생성 후 그래프를 그려보자
import numpy as np
# np.random.randn 함수는 표준 정규분포에서 난수를 생성하는 함수이다.
# cumsum()은 누적합을 구하는 함수이다.
plt.plot(np.random.randn(50).cumsum())
앞의 데이터 시각화 첫장 plot 사용법을 설명할 때 사용했던 예제도 선 그래프이다
x=np.linspace(0,10,100)
plt.plot(x, np.sin(x), 'o')
plt.plot(x, np.cos(x))
plt.show()
Seaborn을 활용하면 다음과 같이 그릴 수 있다.
sns.lineplot(x=x, y=np.sin(x))
sns.lineplot(x=x, y=np.cos(x))
히스토그램은 도수분포표를 그래프로 나타낸 것이다
가벼운 예시로 히스토그램을 만들어본다.
# 그래프 데이터
mu1, mu2, sigma = 100, 130, 15
x1 = mu1 + sigma*np.random.randn(10000)
x2 = mu2 + sigma*np.random.randn(10000)
# 축 그리기
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
# 그래프 그리기
patches = ax1.hist(x1, bins=50, density=False) # bins는 x값을 총 50개 구간으로 나눈다는 뜻
patches = ax1.hist(x2, bins=50, density=False, alpha=0.5)
ax1.xaxis.set_ticks_position('bottom') # x축의 눈금을 아래 표시
ax1.yaxis.set_ticks_position('left') # y축의 눈금을 왼쪽에 표시
# 라벨, 타이틀 달기
plt.xlabel('Bins')
plt.ylabel('Number of Values in Bin')
ax1.set_title('Two Frequency Distributions')
# 보여주기
plt.show()
다시 tips 데이터로 돌아가서 tips 데이터의 total_bill과 tips에 대해 히스토그램을 만들어 본다.
sns.histplot(df['total_bill'], label='total_bill')
sns.histplot(df['tip'], label='tip').legend() # legend()를 이용하여 label을 표시해 준다.
아래는 전체 결제 금액 대비 팀의 비율을 나타내는 히스토그램을 그려본다
df['tip_pct'] = df['tip'] / df['total_bill']
df['tip_pct'].hist(bins=50)
kind='kde'
로 확률 밀도 그래프로 나탄낼 수도 있다.
df['tip_pct'].plot(kind='kde')
지금까지 정말 많이 사용되는 막대그래프(bar graph), 꺾은선 그래프(line graph), 산점도(scatter plot), 히스토그램(histogram) 이 4가지 그래프에 대해서 알아봤다.
수치형 데이터인지, 범주형 데이터인지에 따라 어떤 plot을 사용할지 생각하는 것이 중요하다.
이번에는 시계열 데이터를 다루는 것을 알아보자
직접 다운받아도 괜찮고 Seaborn의 load_dataset()
메서드를 활용해도 좋다.
csv_path = "flights.csv"
data = pd.read_csv(csv_path)
flights = pd.DataFrame(data)
flights
# flights = sns.load_dataset("flights") # load_dataset 사용
# df = pd.DataFrame(flights)
데이터는 연도의 각 달별로 탑승객 수를 보여준다.
sns.barplot(data=flights, x='year', y='passengers')
sns.pointplot(data=flights, x='year', y='passengers')
sns.lineplot(data=flights, x='year', y='passengers')
월 별로 나눠보기 위해 hue
인자에 'month'를 할당
sns.lineplot(data=flights, x='year', y='passengers', hue='month', palette='ch:50')
plt.legend(bbox_to_anchor=(1.03, 1), loc=2) # legend 그래프 밖에 추가
sns.histplot(flights['passengers'])
Heatmap은 방다핸 양의 데이터와 현상을 수치에 따른 색상으로 나타내는 것으로, 데이터 차원에 대한 제한은 없으나 모두 2차원으로 시각화하여 표현합니다.
예제 데이터의 연도와 달에 대해 탑승객 수를 heatmap으로 나타내보자
pandas의 dataframe의 pivot()
메서드를 사용한다
pivot
이란, 어떤 축, 점을 기준으로 바꾸다 라는 뜻으로, 데이터 표를 재배치할 때도 pivot이라는 단어를 사용한다(엑셀, Database에도 등장하는 용어)
Heatmap을 그리기 위해 데이터를 pivot해야 하는 경우가 있다.
flights(DataFrame)의 탑승객 수를 year과 month로 pivot하고 heatmap을 그려보자
pivot = flights.pivot(index='year', colums='month', values='passengers')
pivot
sns.heatmap(pivot)
heatmap에 다양한 옵션을 줄 수 있다.
sns.heatmap(pivot, linewidths=.2, annot=True, fmt="d")
sns.heatmap(pivot, cmap="YlGnBu")