본문 바로가기
데이터 분석/시각화

[기타] Matplotlib 한글 폰트 설정 - Window 10

by 부자 꽁냥이 2020. 5. 31.

안녕하세요~ '꽁냥이'입니다.

 

제가 시각화 관련 포스팅을 진행하려고 하는데요. 근데 포스팅을 준비하다가 '이거는 사전에 미리 알려드려야겠다' 하는 것들이 생기더라고요. 이런 것들은 앞으로 '[기타]~~'에 정리하려고 합니다.

 

그중 첫 번째는 바로 Matplotlib에서 한글 설정하는 법입니당~♥

 

여기서 다루는 내용은 다음과 같습니다.

 

1. 한글 깨짐 현상

2. 한글 폰트를 시스템에 추가하기!
3. 폰트를 개별적으로 적용하기
4. 폰트를 일괄적으로 적용하기

5. 기본 설정 파일에서 폰트를 설정하기

 

여기서는 Window 10 환경에서 한글을 설정하는 법을 다룹니다. Mac OS나 Linux 환경에서 한글을 설정하는 방법은 아래의 글을 링크로 남겨드리니 참고하시면 되겠습니당~

 

Mac OS : https://financedata.github.io/posts/matplotlib-hangul-for-osx.html

Ubuntu Linux : https://financedata.github.io/posts/matplotlib-hangul-for-ubuntu-linux.html

 

이번 포스팅은 아래의 글을 참고하였습니당~

 

한글 깨짐 현상에 대한 해결방법을 세세하게 다룬 글 :

https://teddylee777.github.io/visualization/matplotlib-%EC%8B%9C%EA%B0%81%ED%99%94-%ED%95%9C%EA%B8%80%ED%8F%B0%ED%8A%B8%EC%A0%81%EC%9A%A9

 

LIST

1. 한글 깨짐 현상

그럼 시작해볼까요?

우선 아래 코드를 보겠습니당~

import matplotlib.pyplot as plt

## 예제용 데이터
frequency = [10,11,5,8,11] ## 빈도수
label = ['가','나','다','라','마'] ## 그룹

## 시각화 하기
fig = plt.figure(figsize=(10,10))

xpos = list(range(len(frequency))) ## 네모 바가 그려질 x 좌표

plt.bar(xpos, height=frequency) ## 바차트 그리기
plt.xticks(xpos, label) ## 바차트 눈금 설정
plt.title('그룹별 빈도수')
plt.show()

이 코드는 각 그룹별(가~마)로 빈도수를 바 차트로 출력하는 코드입니다.

(바 차트를 그리는 법은 언능언능 준비해서 포스팅하겠습니당~)

 

보시면 알겠지만 타이틀과 그룹 이름이 한글로 되어 있습니다. 위 코드를 실행하면 어떻게 될까요?

 

 

에공. 위 그림에서 빨간 동그라미 안을 보시면 타이틀은 '그룹별 빈도수', 눈금 라벨은 '가, 나, 다, 라, 마'가 나와야 하는데 깨져버렸네요. ㅠ.ㅠ

 

원인은 바로 Matplotlib에서 기본으로 설정되어있는 폰트에 있는데요. 확인 해봅시당~!

 

Matplotlib에서 기본 설정 내용은 rcParams 필드를 통해서 볼 수 있고요. rcParams 필드는 matplotlib 모듈에 속해 있으므로 다음과 같이 임포트 합니다.

import matplotlib as mat

다음으로 rcParams는 어떤 정보를 담고 있는지 직접 확인해봅시다.

print(mat.rcParams)

실행결과

보시면 알겠지만 엄청나게 많은 내용이 있습니다. 그중에서 우리가 원하는 폰트 정보는 'font.family'를 통해 볼 수 있습니다. (기본 설정 내용에 대한 더 많은 정보를 알고싶다면 여기에 들어가보세요)

print(mat.rcParams['font.family'])

실행결과

확인해 보니 기본 폰트가 'sans-serif'로 설정되어 있었군요!

아마도 Matplotlib에서 제공하는 'sans-serif'가 한글과 만나면 오류가 생기는 것이 아닌가 싶어요(인터넷 검색해봤는데 정확히 왜 오류가 나는지는 찾지 못했어요~ 혹시 아는 분이 있다면 알려주십셩~>0<)

 

자~ 이제 원인을 알았으니 해결을 해봐야겠죠?

우선 한글 폰트를 사용하려면 시스템에 폰트를 추가해야 하는데요. 방법을 알아봅시당~

 


   2. 한글 폰트를 시스템에 추가하기!

1) 개인적으로 국민 폰트라고 생각하는 나눔 글꼴을 아래 링크로 들어가셔서 다운로드 합시당~

 

나눔 글꼴 다운로드 : https://hangeul.naver.com/2017/nanum

 

2) 다운받으셨으면 압축을 풀어 줍시당~ 저는 NanumFontSetup_TTF_ALL.zip 파일을 다운받았네요.

 

3) 그런 다음 NanumFontSetup_TTF_ALL 폴더로 들어가셔서 전체 선택 (Ctrl + A)을 하고 복사를 해줍니당~

 

 

 

4) 마지막으로 로컬 디스크 (C:) -> Windows -> Fonts 폴더로 이동하고 여기에 방금 복사한 폰트들을 붙여 넣기 해주시면 끝~~!!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

자! 그럼 한글 폰트도 준비되었으니 Matplotlib 폰트 설정을 해보겠습니다.

 

반응형

   3. 폰트를 개별적으로 적용하기

'폰트를 개별적으로 적용한다'는 말은 그래프를 구성하고 있는 요소(타이틀, 눈금 라벨, 범례 등)별로 폰트를 적용하겠다는 뜻입니다. 우리가 살펴본 예제에서는 타이틀과 눈금 라벨이 한글로 되어있었으니 이 2개의 요소에 한글을 다른 스타일로 적용시켜볼 겁니당~

 

1) Matplotlib에서 폰트 정보를 보거나 설정하는 것은 font_manager에서 할 수 있어요~ 임포트 해줍시당~

import matplotlib.font_manager as fm

2) 그다음으로 FontProperties 클래스의 인스턴스를 생성해줘야 돼요. 여기에는 적용할 폰트의 경로, 폰트 사이즈 등을 초기값으로 설정할 수 있어요. 우리는 타이틀, 눈금 라벨 요소에 한글을 각각 다르게 적용해보려고 하니까 두 개의 FontProperties클래스의 인스턴스를 생성할 겁니다. 그리고 다음과 같이 타이틀은 나눔 펜, 눈금 라벨은 나눔 고딕을 적용하고 사이즈는 각각 30, 25로 설정할게요.

## 폰트 이름
title_font_name = 'NanumGothic'
tick_label_font_name = 'Nanum Pen Script'

## 폰트 경로
title_font_path = [f.fname for f in fm.fontManager.ttflist if title_font_name in f.name][0]
tick_label_font_path = [f.fname for f in fm.fontManager.ttflist if tick_label_font_name in f.name][0]

## 폰트 사이즈
title_font_size = 30
tick_label_font_size = 25

## FontProperties 인스턴스 생성
title_font_prop = fm.FontProperties(fname = title_font_path, size=title_font_size)
tick_label_font_prop = fm.FontProperties(fname = tick_label_font_path, size=tick_label_font_size)

나눔 고딕, 나눔 펜 이외에도 아래 코드를 실행하면 더 많은 나눔 글꼴을 확인할 수 있으니 맘에 드는 걸로 고르시면 되겠습니당. 

for f in fm.fontManager.ttflist:
    if 'Nanum' in f.name:
        print(f.name)

※ 여기서 잠깐

나눔글꼴을 처음으로 받으실 경우 다음의 코드에서 에러가 날 수 있어요.

## 폰트 경로
title_font_path = [f.fname for f in fm.fontManager.ttflist if 'NanumGothic' in f.name][0]
tick_label_font_path = [f.fname for f in fm.fontManager.ttflist if 'Nanum Pen Script' in f.name][0]

왜냐 하면 나눔 고딕과 나눔 펜을 찾지 못하기 때문인데요. 이게 윈도우에서만 그런 것 같습니다. 정확한 원인은 모르겠어요. 이 경우 아래의 코드를 실행해주면 문제없이 잘 동작할 거예요.(처음 한 번만 실행하면 돼요~~)

fm._rebuild()

3) 우리가 생성한 2개의 FontProperties 인스턴스를 타이틀과 눈금 라벨에 적용합니다~

plt.xticks(xpos, label, fontproperties=tick_label_font_prop) ## 바차트 눈금 설정
plt.title('그룹별 빈도수', fontproperties=title_font_prop)

 4) 드디어 우리가 설정한 한글이 제대로 나오는지 확인해 보로 시간입니다. 아래 코드는 위 코드를 종합한 것입니다. 실행해 볼까요?

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

## 폰트 이름
title_font_name = 'NanumGothic'
tick_label_font_name = 'Nanum Pen Script'

## 폰트 경로
title_font_path = [f.fname for f in fm.fontManager.ttflist if title_font_name in f.name][0]
tick_label_font_path = [f.fname for f in fm.fontManager.ttflist if tick_label_font_name in f.name][0]

## 폰트 사이즈
title_font_size = 30
tick_label_font_size = 25

## FontProperties 인스턴스 생성
title_font_prop = fm.FontProperties(fname = title_font_path, size=title_font_size)
tick_label_font_prop = fm.FontProperties(fname = tick_label_font_path, size=tick_label_font_size)

## 예제용 데이터
frequency = [10,11,5,8,11] ## 빈도수
label = ['가','나','다','라','마'] ## 그룹

## 시각화 하기
fig = plt.figure(figsize=(10,10))

xpos = list(range(len(frequency))) ## 네모 바가 그려질 x 좌표

plt.bar(xpos, height=frequency) ## 바차트 그리기
plt.xticks(xpos, label, fontproperties=tick_label_font_prop) ## 바차트 눈금 설정
plt.title('그룹별 빈도수', fontproperties=title_font_prop)
plt.show()

와우~ 타이틀과 눈금라벨에 개별적으로 한글이 적용된 것을 확인할 수 있습니다~~!!

 


   4. 폰트를 일괄적으로 적용하기

폰트를 개별적으로 설정하는 것도 좋지만

매번 요소마다 적용하는 것이 여간 귀찮은 일이 아닐 겁니당~

이럴 때는 하나의 폰트를 모든 요소에 일괄적으로 적용하면 굉장히 편할 거예요~

 

1) 아까랑 똑같이 폰트가 나눔 고딕인 FontProperties 인스턴스를 하나 생성해주려고 하는데 위에서 말씀드린 코드를 실행해보니 미처 생각하지 못한 것을 발견했습니다.

for f in fm.fontManager.ttflist:
    if 'Nanum' in f.name:
        print(f.name)

실행 결과

2) 보이시죠? 나눔 고딕만 네개가 있네요. 이게 나눔 고딕이라는 한 패밀리 안에 네개의 다른 글씨체가 있더군요. 따라서 이름을 가지고 하면 애매할 수 있어서 폰트의 경로를 가지고 폰트를 설정해보겠습니다. 먼저 나눔고딕 기본폰트의 경로를 알아보겠습니다. 아래의 코드를 실행해주세요~

for f in fm.fontManager.ttflist:
    if 'NanumGothic' == f.name:
        print(f'Font: {f.name}, Path: {f.fname}')

실행 결과

3) 보니까 같은 나눔고딕이라 하더라도 굵기가 다른 폰트들이 있네요~ 저는 위에서 세 번째 걸로 정했습니다.

개별적으로 설정할 때와 마찬가지로 FontProperties 인스턴스를 생성하고요~ 그리고 인스턴스를 통해 폰트 이름을 얻습니다. 아래의 코드를 참고하세요. 

## 폰트 경로
font_path = 'C:/Users/uyytre/AppData/Local/Microsoft/Windows/Fonts/NanumGothic.ttf'

## FontProperties 인스턴스 생성
font_prop = fm.FontProperties(fname=font_path)

## 폰트 이름
font_name = font_prop.get_name()

4) 그리고 아래의 코드를 통해 일괄적으로 폰트를 적용할 수 있습니다.

 

## 폰트 일괄 설정
mat.rc('font',family=font_name)

5) 자~ 코드를 종합하면 아래와 같고요~ 한번 실행해보세요~

import matplotlib as mat
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
## 폰트 경로
font_path = 'C:/Users/uyytre/AppData/Local/Microsoft/Windows/Fonts/NanumGothic.ttf'

## FontProperties 인스턴스 생성
font_prop = fm.FontProperties(fname=font_path)

## 폰트 이름
font_name = font_prop.get_name()

## 폰트 일괄 설정
mat.rc('font',family=font_name)

## 예제용 데이터
frequency = [10,11,5,8,11] ## 빈도수
label = ['가','나','다','라','마'] ## 그룹

## 시각화 하기
fig = plt.figure(figsize=(10,10))

xpos = list(range(len(frequency))) ## 네모 바가 그려질 x 좌표

plt.bar(xpos, height=frequency) ## 바차트 그리기
plt.xticks(xpos, label) ## 바차트 눈금 설정
plt.title('그룹별 빈도수')
plt.show()

타이틀과 눈금 라벨이 잘 나온 것을 확인할 수 있습니다~~ 짝짝!!

 

※ 여기서 잠깐 

근데 이것보다 더 간단하게 해결할 수 있습니다. 아까 Matplotlib에서 기본으로 설정되어 있는 내용을 보기 위해서 rcParams 필드를 사용했던 거 기억나시죵?? 바로 이걸 이용하는 겁니다. 아래의 코드를 통해서 폰트를 지정합니다.

mat.rcParams['font.family'] = 'NanumGothic'

아래의 코드는 위와 똑같은 결과를 출력합니다.

import matplotlib.pyplot as plt
import matplotlib as mat

## 폰트 설정
mat.rcParams['font.family'] = 'NanumGothic'

## 예제용 데이터
frequency = [10,11,5,8,11] ## 빈도수
label = ['가','나','다','라','마'] ## 그룹

## 시각화 하기
fig = plt.figure(figsize=(10,10))

xpos = list(range(len(frequency))) ## 네모 바가 그려질 x 좌표

plt.bar(xpos, height=frequency) ## 바차트 그리기
plt.xticks(xpos, label) ## 바차트 눈금 설정
plt.title('그룹별 빈도수')
plt.show()

어때요? 훨씬 간단하지요?!

 


   5. 기본 설정 파일에서 폰트를 설정하기

지금까지 살펴본 한글 폰트 설정 방법에는 한 가지 치명적인 문제가 있는데요. 그건 바로 실행할 때마다 설정을 해줘야 하는 겁니다. 비록 몇 줄 안 되는 코드지만 매번 설정하기에는 번거로운 일이지요~ 하지만 기본 설정 파일을 찾아서 수정 한 번만 해주면 매번 설정할 필요 없이 한글이 잘 출력된답니당~

 

1) 먼저 Matplotlib의 기본 설정 파일을 찾으셔야 하는데요. 아래 코드를 실행해서 찾아볼게요.

import matplotlib as mat

## 기본 설정 파일 경로
print(mat.matplotlib_fname())

실행 결과

2) 자 위의 경로에서 끝부분 즈음에 'mpl-data'라고 보이시나요? 이 폴더로 들어가 줍시다~ 그러면 아래 그림과 같이 'matplotlibrc'라는 파일이 보일 거예요.

3) 이 파일을 메모장으로 열어 줍시당~ 그리고 'Ctrl+F'를 통해서 'font.family'를 입력하고 아래 그림처럼 '#font.family : sans-serif' 부분을 찾아줍시당~

 

 

 

4) 여기에서 #을 지우고 왼쪽 그림과 같이 'font.family' 부분만 수정하고 저장해 줍시당~

 

 

 

 

 

 

이제는 주피터 노트북을 껐다 켜도, 커널을 재실행해도 한글 폰트를 따로 설정해주지 않아도 한글이 출력되는 마법을 보실 수 있어요~ >0<

반응형

- 포스팅을 마치며

글을 쓰다 보니 생각보다 쓸게 많고 그림도 많이 들어가서  내용이 길어진 듯하네요. 그래도 인내심을 갖고 지금까지 '꽁냥이의 긴 글' 읽어주셔서 감사하고요~ 

 

아무래도 한국에서 일하다 보면 그래프에 한글을 넣어야 할 때가 많은데 오늘 배운 한글 설정 방법이 많은 도움이 될 거라 믿어요~

 

혹시라도 제가 잘못알고 있는 내용이 있다면 알려주시면 감사하겠고, 궁금한 점이 있다면 댓글로 남겨주세요~

최대한 빠르게 답변 해드릴게요.

 

꽁냥이의 다음 포스팅도 기대해주시고 그럼 안녕히 계세요~


댓글


맨 위로