기본 콘텐츠로 건너뛰기

[python] matplotlib으로 그래프 만들기- 다변량그래프+3d, 밀집도그래프, 육각그래프, 패턴, 텍스트 설정까지

Matplotlib 그래프 2 1편은 아래에서 확인하실 수 있습니다:) https://wonhwa1.blogspot.com/2022/11/python-matplotlib.html 데이터 준비 1편에서 사용한 csv데이터를 준비해 주세요. 또는 아래의 링크에서 다운받으실 수 있습니다. https://www.kaggle.com/imakash3011/customer-personality-analysis 다변량 그래프 그리기 다변량 그래프는 변수가 여러 개 있는 그래프입니다. 이번 포스팅에는 변수를 4개를 추가하여 그래프를 그리는 방법을 알아보도록 하겠습니다. x축: MntMeatProducts(육류구매량) y축: MntWines(와인구매량) 색구분: Edu_level(학력) 사이즈구분: NumWebPurchases(웹사이트구매횟수) 이렇게 4개의 변수를 그래프로 표현해 보겠습니다. 기존 csv를 불러온 df에서 null 값이 있으면 0으로 일괄대체를 해준 후 나머지 과정을 진행합니다. 먼저 학력별로 색 구분을 하려면 str데이터인 학력을 문자에서 숫자로 변환하는 작업이 필요합니다. 이 작업을 아래의 함수를 써서 학력을 숫자로 바꾼 후, 바꾼 숫자들을 'Edu_level'이라는 학력 컬럼을 새로 만들어 입력 하겠습니다. import pandas as pd import matplotlib.pyplot as plt from matplotlib import font_manager,rc # 한글 폰트 설정 font_location = 'C:/Windows/Fonts/MALGUNSL.TTF' #맑은고딕 font_name = font_manager.FontProperties(fname=font_location).get_name() rc('font',family=font_name) #데이터 셋 불러오기 df = pd.read_csv('marketing_campaign.csv',sep='\t') # nul

[python] matplotlib으로 그래프 만들기- 히스토그램, 산점도, 박스그래프, 파이그래프

Matplotlib이란?

matplotlib은 python에서 데이터 시각화를 도와주는 라이브러리입니다.

그럼 matplotlib을 이용해 다양한 종류의 그래프를 바로 그려 보도록 하겠습니다.


데이터 준비

오늘 시각화할 데이터는 kaggle의 'Customer Personality Analysis' Datasets를 이용하여 그래프를 시각화 해보겠습니다.

아래의 링크에서 csv파일을 다운받아 주세요.

https://www.kaggle.com/imakash3011/customer-personality-analysis


이 데이터는 한 회사 고객들의 구매 정보 및 고객 정보등을 포함하고 있습니다.

각 열의 내용은 아래와 같습니다.

People

  • ID: Customer's unique identifier (고객식별id)
  • Year_Birth: Customer's birth year (출생년도)
  • Education: Customer's education level (학력)
  • Marital_Status: Customer's marital status (결혼상태)
  • Income: Customer's yearly household income (수입)
  • Kidhome: Number of children in customer's household (자녀 수)
  • Teenhome: Number of teenagers in customer's household (10대 자녀 수)
  • Dt_Customer: Date of customer's enrollment with the company (회원가입날짜)
  • Recency: Number of days since customer's last purchase (마지막구매 후 경과일자)
  • Complain: 1 if the customer complained in the last 2 years, 0 otherwise (지난 2년간 컴플레인 여부)
Products
  • MntWines: Amount spent on wine in last 2 years (지난 2년간 와인 구매량)
  • MntFruits: Amount spent on fruits in last 2 years (지난 2년간 과일 구매량)
  • MntMeatProducts: Amount spent on meat in last 2 years (지난 2년간 육류 구매량)

  • MntFishProducts: Amount spent on fish in last 2 years (지난 2년간 수산물 구매량)
  • MntSweetProducts: Amount spent on sweets in last 2 years (지난 2년간 간식류 구매량)
  • MntGoldProds: Amount spent on gold in last 2 years (지난 2년간 귀금속 구매량)
그 밖에도 여러 열이 있는데 나머지는 위의 링크에 들어가면 확인할 수 있습니다.

필요모듈 import 및 폰트설정

그래프 생성에 필요한 matplotlib 라이브러리와

데이터 불러오는 데 필요한 pandas 라이브러리를 불러와 줍니다.

그리고 그래프에 한글을 사용하기 위해서 한글 폰트를 설정해 주어야 하기 때문에 폰트설정까지 해 보도록 하겠습니다.

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager,rc

# 한글 폰트 설정
font_location = 'C:/Windows/Fonts/MALGUNSL.TTF' #맑은고딕
font_name = font_manager.FontProperties(fname=font_location).get_name()
rc('font',family=font_name)

그리고 그래프에 한글을 사용하기 위해서 한글 폰트를 설정해 주어야 하기 때문에 폰트 설정까지 해 보도록 하겠습니다.

저는 '맑은 고딕'을 한글 폰트로 사용하겠습니다.

다른 폰트를 사용하고 싶다면 변경해 주시면 됩니다.

데이터 셋 준비

위에서 다운받은 csv파일을 열어 줍니다.

이 csv파일은 ,가 아니라 tab으로 나누어져있어 sep = \t으로 설정하여 열어주어야 합니다.

그후 .head()를 사용하여 데이터 내용을 확인해 보도록 하겠습니다.

#데이터 셋 불러오기
df = pd.read_csv('marketing_campaign.csv',sep='\t')

print(df.head())



29개의 컬럼으로 데이터가 이루어져 있습니다.

각각 컬럼에 대한 설명은 위를 확인해 주세요.

이제 위의 데이터로 그래프를 만들어 보도록 하겠습니다.


히스토그램 그래프

히스토그램은 도수분포를 그래프화 시킨 건데 보통 변수 1개를 가지고 빈도를 구하여 그래프를 그립니다.

고객의 자녀 수를 히스토그램으로 만들어 보도록 하겠습니다.

#############히스토그램##############
#그래프를 그리기 위한 기본 틀 생성
fig = plt.figure()
axes1=fig.add_subplot(1,1,1)

#히스토그램 그래프 만들기(변수1개)
axes1.hist(df['Kidhome'],bins = 8) #가정의 자녀 수 히스토그램 #bins는 x축 칸(간격)조정
#제목설정
axes1.set_title('고객 가정의 자녀 수 히스토그램')
#x축라벨링
axes1.set_xlabel('자녀 수')
#y축라벨링
axes1.set_ylabel('빈도')
plt.show()

위와 같이 히스토그램이 만들어 졌습니다.

데이터프레임으로도 히스토그램을 만들 수 있는데요 방법은 아래와 같습니다.

###다른방법으로 히스토그램
ax = plt.subplots()
ax = df['Kidhome'].plot.hist()
plt.show()

산점도 그리기

이번에는 matplotlib으로 산점도를 생성해보도록 하겠습니다.

산점도는 x,y 값을 점으로 찍어 그래프를 그리는방법인데,

여기서는 간식구매량을 x, 과일구매량을 y로 설정하여 산점도를 생성해 보겠습니다.

#산점도 그리기(변수2개)
scatter_plot = plt.figure()
axes2 = scatter_plot.add_subplot(1,1,1)

axes2.scatter(df['MntSweetProducts'],df['MntFruits'])
#제목설정
axes2.set_title('간식구매량 및 과일구매량 산점도')
#x축라벨링
axes2.set_xlabel('간식구매량')
#y축라벨링
axes2.set_ylabel('과일구매량')

#산점도 그리는 다른 방법
fig2,ax2 = plt.subplots()
ax2 = df.plot.scatter(x='MntSweetProducts',y='MntFruits',ax=ax2)
plt.show()

[산점도 그래프]

[df로 그린 산점도 그래프]

이렇게 2가지 방법으로 산점도를 그려 봤습니다.


박스그래프

이제 박스그래프를 그려보도록 하겠습니다.

박스그래프는 이산형 변수와 연속형 변수를 함께 사용하여 그리는데

이산형 변수는 성별의 male, female 과 같이 확실히 구분되는 값을 말하고,

연속형 변수는 구매량과 같은 연속적인 숫자가 있는 범위의 값을 말합니다.

이번에는 데이터의 Education(학력)을 이산형변수로,

Income(수입)을 연속형 변수로 하여 박스그래프를 그려 보도록 하겠습니다.

income값 중에 null인 값이 있어 null을 0으로 대체한 후 그래프를 생성하도록 합니다.

#############박스그래프##############
# box 그래프 그리기(이산형 변수와 연속형 변수를 함께 사용)
# 이산형: 학력
# 연속형: 수입
# df Null값 0으로 대체
df['Income'] = df['Income'].fillna(0)

boxplot = plt.figure()
axes3 = boxplot.add_subplot(1,1,1)
axes3.boxplot([df[df['Education'] == 'Basic']['Income'], 
               df[df['Education'] == 'Graduation']['Income'],
               df[df['Education'] == '2n Cycle']['Income'],
               df[df['Education'] == 'Master']['Income'], 
               df[df['Education'] == 'PhD']['Income']], 
               labels=['고졸','대졸','2nCycle','석사','박사'])

axes3.set_xlabel('학력')
axes3.set_ylabel('수입')
axes3.set_title('학력에 따른 수입 박스그래프')
plt.show()

여기서 Basic은 고등학교 졸업, Graduation은 학사, Master은 석사, PhD는 박사를 의미합니다.

2nCycle(second cycle)은 학사~석사 라고 하는데 석사 과정에 있는 사람을 말하는 것 같습니다.

그리고 df로도 박스 그래프를 그릴 수 있는데요 그전에 기존df의 피벗팅이 필요합니다.

아래와 같이 필요한 내용만 데이터를 뽑아 주세요.

# df피벗
#교육, 수입부분만뽑기
df_pv=df.iloc[:,0:5]
df_pv = df_pv.drop(['Year_Birth','Marital_Status'],axis=1) #열삭제시 axis=1
print(df_pv.head())

그 후 피벗을 진행해 줍니다.

#교육상태를 컬럼으로 피벗
df_pv = df_pv.pivot_table(
    index='ID',
    columns='Education',
    values='Income')
print(df_pv.head())

이제 다시 박스 그래프로 시각화 해보도록 하겠습니다.

#df로 박스그래프 만들기
fig3,ax3 = plt.subplots()
ax3 = df_pv.plot.box(ax= ax3)
plt.show()

위와 같이 그래프가 잘 만들어졌습니다.


파이그래프

마지막으로, 파이그래프를 그려보도록 하겠습니다.

파이그래프를 그릴 데이터로는 학력의 Education 컬럼에서 학력을 가진 고객이 각각 몇 %를 차지하는지 계산 후 파이그래프를 그려주도록 하겠습니다.

파이그래프를 그릴 때 소수점 1자리까지만 표시 후 뒤에 %를 다 붙여 주도록 하겠습니다.

#######파이그래프 그리기#######
#학력 카운트
count = df.groupby('Education').Education.count()
#전체 고객 중 해당 학력을 가지고 있는 비율 구하기
ratio = count/sum(count)
#그래프에 표시할 인덱스
labels = count.index
#파이그래프 그리기
pie = plt.pie(ratio, labels=labels, autopct='%.1f%%')
plt.show()



이렇게 기본 파이그래프가 그려졌습니다.

파이그래프를 띄어서 그리고 싶을 때는 explode를 아래와 같이 설정해 주면 됩니다.

여기에 더해 그림자를 추가하고 싶으면 shadow=True 로 변경해 주면 됩니다.

그래프 색을 바꾸고 싶을 때는 colors에 해당 컬러 코드를 입력해 주세요.

https://colorhunt.co/

컬러 팔레트 참고 사이트 입니다. 마음에 드는 색조합을 선택해 드래그 하면 복사가 됩니다.

#explode=파이를 띄울 간격
#shadow=True 파이 그림자 설정
#colors=그래프 색 변경
pie = plt.pie(ratio, labels=labels, autopct='%.1f%%',explode=[0,0,0.05,0,0.1],shadow=True,
             colors=['#FAF4B7','#ECC5FB','#C6EBC5','#CDF0EA','#FFFAE7'])
plt.show()



이렇게 커스터마이즈 한 그래프가 생성되었습니다.


전체코드

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager,rc

# 한글 폰트 설정
font_location = 'C:/Windows/Fonts/MALGUNSL.TTF' #맑은고딕
font_name = font_manager.FontProperties(fname=font_location).get_name()
rc('font',family=font_name)
#데이터 셋 불러오기
df = pd.read_csv('marketing_campaign.csv',sep='\t')

print(df.head())

#############히스토그램##############
#그래프를 그리기 위한 기본 틀 생성
fig = plt.figure()
axes1=fig.add_subplot(1,1,1)

#히스토그램 그래프 만들기(변수1개)
axes1.hist(df['Kidhome'],bins = 8) #가정의 자녀 수 히스토그램 #bins는 x축 칸(간격)조정
#제목설정
axes1.set_title('고객 가정의 자녀 수 히스토그램')
#x축라벨링
axes1.set_xlabel('자녀 수')
#y축라벨링
axes1.set_ylabel('빈도')
#plt.show()

###다른방법으로 히스토그램
ax = plt.subplots()
ax = df['Kidhome'].plot.hist()
#plt.show()

#############산점도##############
#산점도 그리기(변수2개)
scatter_plot = plt.figure()
axes2 = scatter_plot.add_subplot(1,1,1)

axes2.scatter(df['MntSweetProducts'],df['MntFruits'])
#제목설정
axes2.set_title('간식구매량 및 과일구매량 산점도')
#x축라벨링
axes2.set_xlabel('간식구매량')
#y축라벨링
axes2.set_ylabel('과일구매량')


#산점도 그리는 다른 방법
fig2,ax2 = plt.subplots()
ax2 = df.plot.scatter(x='MntSweetProducts',y='MntFruits',ax=ax2)
#plt.show()

#############박스그래프##############
# box 그래프 그리기(이산형 변수와 연속형 변수를 함께 사용)
# 이산형: 학력
# 연속형: 수입
# df Null값 0으로 대체
df['Income'] = df['Income'].fillna(0)

boxplot = plt.figure()
axes3 = boxplot.add_subplot(1,1,1)
axes3.boxplot([df[df['Education'] == 'Basic']['Income'], 
               df[df['Education'] == 'Graduation']['Income'],
               df[df['Education'] == '2n Cycle']['Income'],
               df[df['Education'] == 'Master']['Income'], 
               df[df['Education'] == 'PhD']['Income']], 
               labels=['고졸','대졸','2nCycle','석사','박사'])

axes3.set_xlabel('학력')
axes3.set_ylabel('수입')
axes3.set_title('학력에 따른 수입 박스그래프')
#plt.show()

#df으로 box plot 그리기

# df피벗
#교육, 수입부분만뽑기
df_pv=df.iloc[:,0:5]
df_pv = df_pv.drop(['Year_Birth','Marital_Status'],axis=1) #열삭제시 axis=1
print(df_pv.head())

#교육상태를 컬럼으로 피벗
df_pv = df_pv.pivot_table(
    index='ID',
    columns='Education',
    values='Income')
print(df_pv.head())

fig3,ax3 = plt.subplots()
ax3 = df_pv.plot.box(ax= ax3)
plt.show()

#######파이그래프 그리기#######
#학력 카운트
count = df.groupby('Education').Education.count()
#전체 고객 중 해당 학력을 가지고 있는 비율 구하기
ratio = count/sum(count)
#그래프에 표시할 인덱스
labels = count.index
#파이그래프 그리기
pie = plt.pie(ratio, labels=labels, autopct='%.1f%%')
plt.show()

#explode=파이를 띄울 간격
#shadow=True 파이 그림자 설정
#colors=그래프 색 변경
pie = plt.pie(ratio, labels=labels, autopct='%.1f%%',explode=[0,0,0.05,0,0.1],shadow=True,
             colors=['#FAF4B7','#ECC5FB','#C6EBC5','#CDF0EA','#FFFAE7'])
plt.show()

참고자료

  • 책 Do it! 데이터 분석을 위한 판다스 입문-이지스퍼블리싱

마무리

오늘은 matplotlib로 그래프 그리는 방법을 알아보았습니다.

위의 그래프들에 대해 더 세세한 사용방법을 알고 싶다면 matplotlib 문서를 참고하시면 됩니다.

다음 시간에는 matplotlib 2편으로 다른 그래프들도 그려보도록 하겠습니다!

댓글

이 블로그의 인기 게시물

[python] geopy를 사용하여 주소를 위,경도 값으로 바꾸기 & 위,경도 값을 주소로 바꾸기

geopy란? geopy는 파이썬 라이브러리로,  주소를 위,경도 숫자 값으로 바꿔 주거나(지오코딩), 반대로 위,경도 값을 사람이 읽을 수 있는 주소로 바꿔줍니다. (이를 역 지오코딩이라 합니다.) 예를 들어, 우리 지역에 있는 카페의 위치를 시각화 한다고 생각해 봅시다. 이 때, 카페 위치를 입력하기 위해서는 컴퓨터가 인식할 수 있도록 위도, 경도의 숫자 값이 필요합니다. 하지만 데이터에 문자 주소만 있다면 이를 바꿔주는 작업이 필요합니다. 이때 geopy를 사용하면 여러 지오코딩 서비스를 연결하여 사용할 수 있습니다. 이중에 OpenStreetMap을 사용하면 따로 api 키를 발급받지 않아도 위경도 변환이 가능합니다. geopy 설치 터미널에 pip install geopy 를 입력하여 설치해 줍니다. 지오코딩 주소 -> 위도, 경도 데이터준비 데이터는 공공데이터 포탈의 '강서구 커피샵 현황'을 사용해 보도록 하겠습니다. 커피샵현황 다운로드   다운받은 csv파일을 열어 주도록 하겠습니다. import pandas as pd df = pd.read_csv('서울특별시 강서구_카페 현황_20220210.csv',encoding='cp949') df.head() 이렇게 한글 도로명주소, 지번주소만 있는 것을 확인할 수 있습니다. 이 주소를 가지고 위도, 경도 값으로 변환해 보겠습니다. 그 전에 주소를 한 번 정리해 주어야 합니다. ( ) 안에 있는 상세 주소 또는 , 뒤에 있는 상세주소를 제거해 주어야 위도, 경도 변환 시 오류가 나지 않습니다. 전처리 데이터 프레임에 있는 도로명 주소, 지번 주소에서 동단위 로만 주소를 남겨 보겠습니다. 예) 서울특별시 강서구 000로 00 -> 000로 00      서울특별시 강서구 00동 000-00 -> 00동 000-0 함수를 하나 만들어 apply를 사용해 주소를 다듬어 준 후, 각각 새로운 열에 추출한 주소를 저장해 줍니다. #주소데이터 전처리

[python] matplotlib으로 그래프 만들기- 다변량그래프+3d, 밀집도그래프, 육각그래프, 패턴, 텍스트 설정까지

Matplotlib 그래프 2 1편은 아래에서 확인하실 수 있습니다:) https://wonhwa1.blogspot.com/2022/11/python-matplotlib.html 데이터 준비 1편에서 사용한 csv데이터를 준비해 주세요. 또는 아래의 링크에서 다운받으실 수 있습니다. https://www.kaggle.com/imakash3011/customer-personality-analysis 다변량 그래프 그리기 다변량 그래프는 변수가 여러 개 있는 그래프입니다. 이번 포스팅에는 변수를 4개를 추가하여 그래프를 그리는 방법을 알아보도록 하겠습니다. x축: MntMeatProducts(육류구매량) y축: MntWines(와인구매량) 색구분: Edu_level(학력) 사이즈구분: NumWebPurchases(웹사이트구매횟수) 이렇게 4개의 변수를 그래프로 표현해 보겠습니다. 기존 csv를 불러온 df에서 null 값이 있으면 0으로 일괄대체를 해준 후 나머지 과정을 진행합니다. 먼저 학력별로 색 구분을 하려면 str데이터인 학력을 문자에서 숫자로 변환하는 작업이 필요합니다. 이 작업을 아래의 함수를 써서 학력을 숫자로 바꾼 후, 바꾼 숫자들을 'Edu_level'이라는 학력 컬럼을 새로 만들어 입력 하겠습니다. import pandas as pd import matplotlib.pyplot as plt from matplotlib import font_manager,rc # 한글 폰트 설정 font_location = 'C:/Windows/Fonts/MALGUNSL.TTF' #맑은고딕 font_name = font_manager.FontProperties(fname=font_location).get_name() rc('font',family=font_name) #데이터 셋 불러오기 df = pd.read_csv('marketing_campaign.csv',sep='\t') # nul