stripplot
strip plot은 카테고리마다의 scatter plot을 그립니다. 그리는 방식으론 jitter를 사용하는데 이 방식은 다른 축의 방향으로 랜덤하게 점을 찍어 겹치는 부분을 줄입니다.
이 방식은 box plot과 violin plot의 보완이 될 수 있습니다.
단 하나의 숫자형 column을 할당한 경우에는 각 점들이 다른 축의 방향으로 랜덤하게 "jittered'된 단일 변량에 대한 분포(univariate distribution)의 형태를 보여줍니다.
tips = sns.load_dataset("tips")
sns.stripplot(data = tips, x = 'total_bill')
y축의 방향에 카테고리 변량을 추가했습니다. 각 카테고리에 해당하는 데이터들의 분포 형태를 비교할 수 있게 되었습니다.
tips = sns.load_dataset("tips")
sns.stripplot(data = tips, x = 'total_bill', y = 'day')
x축에 카테고리 타입을 y축에 숫자 타입 데이터를 설정하면 앞의 예제와는 대조되게 vertical한 모양으로 그래프를 그릴 수 있습니다.
sns.stripplot(data = tips, x = 'day', y = 'total_bill')
hue 키워드 인수를 추가해서 변량을 하나 더 추가할 수 있습니다. 그럼 분류의 개수가 더 늘어 그래프를 쉽게 파악하는데 도움이 될 수 있습니다.
sns.stripplot(data = tips, x = 'day', y = 'total_bill', hue = 'sex')
앞의 예제에서는 hue 키워드 인수에 카테고리 column을 지정했는데, 이산형 숫자 타입의 데이터를 갖는 column도 지정할 수 있습니다.
sns.stripplot(data = tips, x = 'total_bill', y = 'day', hue = 'size')
아래의 예제처럼 dodge = True 키워드 인수를 통해 hue로 나눈 카테고리 값을 완전히 분리시켜 그래프로 표현할 수 있습니다.
sns.stripplot(data = tips, x = 'total_bill', y = 'day', hue = 'size', dodge = True)
swarmplot
swarm plot은 strip plot과 매우 흡사합니다. 하지만 swarm plot에서는 데이터를 마커로 표현할 때 절대로 겹치지 않게 표현합니다. 그 점에서 strip plot(다른 축의 방향으로 랜덤하게 찍을 뿐 겹치게도 직음)과 차이점을 갖습니다. 정확한 데이터의 분포를 표현하기에는 더 없이 좋은 그래프이지만, 아주 큰 스케일의 데이터를 표현하기에는 필요한 너비가 너무 넓어져 이때는 swarm plot을 사용하기에 적합하지 않습니다.
숫자 값을 갖는 데이터의 단일 변량의 분포를 swarm plot으로 표현하고 있습니다. 아래 그래프에서도 살펴볼 수 있듯이 각각의 데이터 마커가 서로 겹치지 않게 표현하고 있습니다.
tips = sns.load_dataset('tips')
sns.swarmplot(data = tips, x = 'total_bill')
y값에 카테고리 자료형을 갖는 column을 추가함으로써 각 카테고리마다의 swarm plot으로 조갰습니다. 아래 예제에서는 각 요일병 총 지출액에 대한 분포를 나타내고 있습니다.
sns.swarmplot(data = tips, x = 'total_bill', y= 'day')
swarm plot을 vertical 방향으로 표현하려면 x 값에 카테고리 자료형을, y 값에 숫자형 데이터를 설정해주면 됩니다.
hue 키워드 인수를 추가해서 변량을 하나 더 추가할 수 있습니다. 그럼 분류의 개수가 더 늘어 그래프를 쉽게 파악하는데 도움이 될 수 있습니다.
sns.swarmplot(data = tips, x = 'total_bill', y= 'day', hue = 'sex`)
아래의 예제처럼 dodge = True 키워드 인수를 통해 hue로 나눈 카테고리 값을 완전히 분리시켜 그래프로 표현할 수 있습니다.
다만 앞의 strip plot과 다르게 swarm plot은 그래프의 크기가 데이터를 표현할만큼 충분히 크지않으면 표현에 생략된 마커가 발생할 수 있습니다.
sns.swarmplot(data = tips, x = 'total_bill', y= 'day', hue = 'sex', dodge = True)
scatter() 메서드의 키워드 인수를 작성해서 사용자가 원하는 시각적효과를 커스텀하게 적용시킬 수 있습니다.
sns.swarmplot(data = tips, x = 'total_bill', y = 'day', marker = 'x', linewidth = 1)
catplot
categorical plot인 catplot은 axes-level(row, col)까지 분류를 나눌수 있습니다. 즉 catplot은 카테고리화를 더 세분화해서 작업할 수 있는 플롯입니다.뿐만 아니라 kind 키워드 인수를 사용하면 axes-level에 사용할 그래프의 유형을 선택할 수 있습니다.
kind를 선택않고 catplot()의 결과를 살펴보면 jittered strip plot의 결과를 얻을 수 있습니다. jittered strip plot은 각 축을 기준하여 데이터의 분포를 점으로 표현하는데, 이 때 점들이 최대한 겹치지않도록 세로 방향으로 무작위로 위치를 찍어주는 플롯입니다.
df = sns.load_dataset('titanic')
sns.catplot(data = df, x = 'age', y = 'class')
kind 키워드 인수에 box라는 문자열을 전달하면 결과물을 box plot으로 표현해줍니다.
sns.catplot(data = df, x = 'age', y = 'class', kind = 'box')
kind를 violin으로 하면 커널 밀도 히스토그램을 그려줍니다.(모양이 바이올린 같다하여 violin plot입니다.)
hue를 sex column에 따라 분류했고 split 키워드 인수에 True 값을 전달했기 때문에 가운데를 기준으로 성별에 따라
커널 밀도 함수가 표현되어 비대칭 되게 표현되고 있습니다.
sns.catplot(data = df, x = 'age', y = 'class', hue = 'sex', kind = 'violin', bw = .25, cut = 0, split = True)
이번에는 kind를 bar plot응로 하고 있습니다. 그런데 더 주목할 점은 axes가 2개인 것처럼 표현됐다는 것입니다.
col 키워드 인수에 sex column name을 설정하였기에 sex 분류에 따라 그래프가 col 단위로 쪼개졌습니다.
그래서 axes-level 단위로 분류 가능하다고 하는 것입니다.
sns.catplot(data = df, x = 'class', y = 'survived', col = 'sex', kind = 'bar', height = 4, aspect = .6)
연속해서 그래프를 그리는 메서드를 여러 차례 사용하면 그에 해당하는 그래프 레이어가 겹쳐서 보이게 됩니다.
swarmplot은 jittered strip plot과 흡사해보이지만 다릅니다. jittered strip plot은 병렬한 방향이지만 정해진 범위 내에서
최대한 겹치지 않게 한 방식이고, swarmplot은 완전히 겹치지 않게 병렬로 점을 찍어 표현하는 방식입니다.
sns.catplot(data = df, x = 'age', y = 'class', kind = 'violin', colors = '.7', inner = None)
sns.swarmplot(data =df, x = 'age', y = 'class', size = 3)
jointplot
두 개의 변수의 분포를 나타낼 때 활용하면 좋은 플롯입니다. histogram과 scatter plot을 동시에 사용해서 시각적 효과를 표현합니다.
jointplot() 메서드를 사용하면 작성할 수 있습니다. 이 때 data 키워드 인수로 penguins의 DataFrame을 전달합니다.
x에는 DataFrame의 column name인 bill_length_mm, y에는 DataFrame의 column name인 bill_depth_mm을 전달하고 있습니다.
penguins = sns.load_dataset('penguins')
sns.jointplot(data = penguins, x = 'bill_length_mm', y = 'bill_depth_mm')
hist plot()과 scatterplot()을 동시에 사용해서 데이터의 분포를 더 자세하고 직관적으로 파악해볼 수 있습니다. 하지만 아래 차트로는 어떤 특징을 찾기 어렵습니다.
hue 키워드인수를 활용하여 species column에 대한 변수를 하나 더 추가했습니다. 앞의 그래프와 달리 scatter plot에 species별로 색상이 다르게 적용되었고 히스토그램으로 표현된 분포가 자동적으로 kde로 변경된 것을 확인할 수 있었습니다.
sns.jointplot(data = penguins, x = 'bill_length_mm', y = 'bill_depth_mm', hue = 'species')
kind 키워드 인수를 하나 추가하고 그 값으로 kde를 전달했습니다. 그 결과로 scatter 분포가 kde의 형태를 띄면서 값의 밀도가 더 눈에 잘보이도록 변경된 것을 확인할 수 있었습니다.
sns.jointplot(data = penguins, x = 'bill_length_mm', y = 'bill_depth_mm', hue = 'species', kind = 'kde')
kind 키워드 인수에 reg 값을 전달해서 선형 회귀에 대한 결과를 그래프로 바로 볼 수 있습니다.
우측 예제에서는 아델리 펭귄에 대한 데이터를 추린 후 아델리 펭귄의 부리에 대한 선형 결과를 구해보았습니다.
ade_penguins = penguins[penguins['species'] == 'Adelie']
sns.jointplot(data = ade_penguins, x = 'bill_length_mm', y = 'bill_depth_mm', kind = 'reg')
hue와 kind = 'reg'는 동시에 사용될 수 없는 옵션입니다.
height, ratio, marginal_ticks 키워드 인수를 추가했습니다. 이 인수를 활용하여 전체 그래프의 크기(height), main과 marginal histogram에 ticks를 표현할지 조절할 수 있습니다.
sns.jointplot(data = ade_penguins, x = 'bill_length_mm', y = 'bill_depth_mm', hue = 'species', height = 7, ratio = 2, marginal_ticks = True)
pairplot
데이터 셋 내의 각 column마다 pair로 경우의 수에 따라 묶고 그에 따른 결과물을 일목요연하게 한번에 확인할 수 있는 플롯입니다.
pairplot()으로 서로 다른 column 간에 비교할 때 가장 단순하게 적용하기 좋은 것이 scatterplot() 입니다.
같은 column이 겹치는 위치에는 histplot()의 결과를 보여줘서 값의 밀도가 어떻게 되는지 보여줍니다.
penguins = sns.load_dataset('penguins')
sns.pairplot(penguins)
의미 있는 관계로 엮기 위해서 hue 키워드 인수에 species를 전달하여 펭귄의 종마다 어떤 분포를 갖는지 분류를 하였습니다.
joint plot 때와 같게도 자동적으로 marginal plot의 형태가 kde로 변경된 것을 확인할 수 있었습니다.
sns.pairplot(penguins, hue = 'species')
marginal plot이 kde가 아닌 histogram으로 표현할 수 도 있습니다. diag_kind 키워드 인수를 사용하면 됩니다.
histogram을 의미하는 hist 문자열을 값으로 전달하면 됩니다.
sns.pairplot(penguins, hue = 'species', diag_kind = 'hist')
다른 column과의 비교하는 영역의 플롯의 종류도 변경할 수 있습니다.
여기서는 kind라는 키워드 인수에 kde를 전달하여 서로 다른 column 간에 결과를 더 보기 좋게 비교할 수 있게 하였습니다.
sns.pairplot(penguins, hue = 'species', kind = 'kde')
x_vars, y_vars 키워드 인수를 활용하여 원하는 column만 추려서 비교를 할 수 도 있습니다.꼭 정방향의 모양이 아니더라도 괜찮습니다.
sns.pairplot(penguins, x_vars = ['bill_length_mm', "bill_depth_mm", "flipper_length_mm"],
y_vars = ['bill_length_mm', "bill_depth_mm"])
중복되는 부분이 있다고 여기는 사람도 분명히 존재할 겁니다. 한 방향으로만 그 분포를 얻으면 된다 싶으면 corner라는 키워드 인수를 True로 설정하면 됩니다. 그럼 삼각형의 모양의 (축의 방향을 고려하지 않았을 때) 중복 없는 결과를 얻을 수 있습니다.
sns.pairplot(penguins, hue = 'species', corner = True)
Pandas pivot table
pivot table이란 데이터 column 중에서 두 개의 column을 각각 row 인덱스, coluumn 인덱스로 사용하여 데이터를 조회하여 펼쳐 놓은 것을 말합니다.
pandas는 지정된 두 column을 각각 row 인덱스와 column 인덱스로 바꾼 후 row 인덱스의 label 값이 첫번째 키의 값과 같고 column 인덱스의 label 값이 두번째 키의 값과 같은 데이터를 찾아서 해당 칸에 넣습니다. 만약 데이터가 존재하지 않으면 해당 칸에 NaN 값을 넣습니다.
Pandas는 pivot table을 만들기 위한 pivot_table() 메서드를 제공합니다. 첫번째 인수로는 DataFrame을, 두번째 인수로는 데이터로 사용할 column 이름을, 세번째 인수로는 row 인덱스로 사용할 column name, 네번째 인수로는 column 인덱스로 사용할 column name을 넣습니다. 그 다음은 aggfunc 키워드 인자가 나오는데 기본적으로 평균 값을 구하도록 default 값이 설정되어 있습니다.
row index로 선실 등급을 나타내는 class column을 column index로 child, man, woman의 분류를 나누는 카테고리 값인 who를 지정했습니다. 그리고 이 때의 값은 생존 여부를 나타내는 survived column을 사용했습니다. aggfunc 키워드 인수를 따로 지정하지 않아서 여기서는 값의 평균을 구하고 있습니다.
pd.pivot_table(titanic, 'survived', index = 'class', columns = 'who')
pd.pivot_table(titanic, values = 'survived', index = 'class', columns = 'who', aggfunc = np.sum)
해당하는 값이 없다면 이는 NaN으로 표현됩니다. 이 값은 pivot_table() 메서드 인자 중 fill_value에 값을 전달하면 해당 값으로 NaN이 처리되게 됩니다.
pd.pivot_table(titanic, values = 'survived', index = 'class', columns = 'deck', aggfunc = np.mean, fill_value = 0)
heatmap()
데이터셋 중 비교하고자 하는 column의 pair가 모두 카테고리 값이거나, 피봇테이블의 결과를 가지고 heatmap()으로 표현하면 각 column 간의 상관 관계를 짙고 옅음으로 표현할 수 있습니다.
타이타닉호 데이터셋 중 선실등급과 사람의 분류에 따라 생존률을 피봇테이블의 결과로 만들었습니다. 그리고 이 피봇테이블을 heatmap()의 인수로 전달했습니다. 또 cmap을 활용하여 "crest"테마를 적용했습니다. 짙은 푸른 빛을 딀 수록 생존율이 높고,
노란빛에 가까울 수록 생존율이 낮습니다.
ttn_cls_who = pd.pivot_table(titanic, 'survived', index = 'class', columns = 'who')
sns.heatmap(ttn_cls_who, cmap = 'crest')
같은 데이터에 이번에는 다른 키워드 인수들을 추가하여 옵션을 달리해봤습니다. annot 키워드 인수에 True 값을 줘서 각 cell마다 value를 표기해줬고, 동시에 fmt 키워드 인수를 사용해서 cell마다 표기한 value의 포맷을 지정해줬습니다. 뿐만 아니라 linewidth를 명시하여 cell 간의 구분을 더 명확하게 지정했습니다.
ttn_cls_who = pd.pivot_table(titanic, 'survived', index = 'class', columns = 'who')
sns.heatmap(ttn_cls_who, cmap = 'mako', annot = True, fmt = ".2f", linewidth = .5)
'데이터 분석 및 시각화 > 데이터 시각화' 카테고리의 다른 글
[SUPERSET] 아파치 슈퍼셋(superset) 소개 및 설치 (0) | 2023.06.04 |
---|---|
[Python] folium (0) | 2023.01.31 |
[Python] Seaborn(barplot, boxplot, violinplot) (0) | 2023.01.27 |
[Python] Seaborn(style 세팅, 카운트 플롯, 히스토그램(displot)) (0) | 2023.01.26 |
[Python] matplotlib - 차트 (0) | 2023.01.26 |