혼공단

[혼공분석] 5주차_Ch.5 데이터 시각화하기

tisteryun 2025. 8. 11. 02:25

안녕하세요! 

어느새 5주차 입니다.

 

5주차는 제가 조금 아는 내용이기도 하고 내용이 조금 짧아서 가볍네요!

저는 지금 막 adsp시험을 보고 이 글을 쓰고 있습니다.

오늘은 46회 adsp 시험이 있던 날인데요

 

한 5일정도... 벼락치기 공부를 하고 시험을 봤는데

잘은 모르겠지만 통과하지 않았을까... 그런 생각을 해봅니다

반응을 살펴보니 오늘 시험이 난이도가 있는 편이었던 것 같긴 한데

음... 답을 모르기도 하고 벼락치기를 한 거라 잘 모르겠네요

 

아무튼 이번 5주차 과제는 늦지 않게 해봅니다!


 

05-1. 맷플롯립 기본요소 알아보기

 

이 소단원의 목표는 간단하게

피겨라는 객체를 이해하고, plot의 크기 바꾸고, subplot으로 여러 그래프를 한번에 출력하는 것입니다.

 

1. figure(피겨)

피겨는 모든 그래프 구성요소를 담고 있는 최상위 객체입니다. 

전체적으로 matplotlib을 활용해 그릴 모든 그래프에 대한 기본 설정을 하는 객체라고 생각하면 편한 것 같습니다. 

 

이 피겨에서 우리는 주로, 그래프의 크기를 설정합니다. 

그래프의 크기는 figsize 매개변수를 통해 변경할 수 있습니다.

plt.figure(figsize=(9, 6))
#기본적인 단위는 인치
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()

figsize 매개변수는 figure() 함수를 통해 설정합니다.

그래프를 그리기 전, 그래프를 그릴 캔버스의 크기를 설정하는 것과 같기 때문에

그래프를 그리는 함수보다 먼저 와야 합니다. 

 

다만 figsize 매개변수를 통해 그래프의 크기를 지정한다고 해도

정확하게 설정한 크기의 그래프가 출력되지 않는 문제가 있는데요

 

바로 DPI가 컴퓨터마다 다르기 때문입니다. 

(*DPI : 1인치를 몇개의 픽셀로 표현하는지를 나타난 지표)

그러나 코랩의 기본 DPI는 72이기 때문에 이를 이용해 보다 정확한 크기의 그래프를 얻을 수 있습니다. 

plt.figure(figsize=(900/72, 600/72))
*픽셀을 dpi로 나누면 인치가 된다!
*인치값을 튜플 안에 넣어야 하기 때문에, 원하는 크기의 픽셀값을 정하고 dpi로 나눠주면 보다 정확한 크기의 그래프 출력 가능하다
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()

 

만약에 그래프의 전반적인 크기를 키우고 싶다면 DPI값을 키우면 됩니다.

코랩의 DPI 값을 72 -> 144로 두배 증가시키면, 

그래프는 물론 x축과 y축, 마커, 라벨까지 모든 요소가 두배 커집니다. 

*현재 dpi값 확인하기
print(plt.rcParams['figure.dpi'])

*dpi값 바꾸기
plt.figure(dpi=144)
plt.rcParams['figure.dpi']=144

 

2. rcParams

rcParams는 맷플롯립 그래프의 기본값을 관리하는 객체입니다.

기본값을 확인할 수도, 변경할 수도 있습니다.

rcParams를 통해 변경된 기본값은 이후 출력되는 모든 그래프에 적용됩니다. 

#dpi 바꾸기
plt.rcParams['figure.dpi'] = 100

#마커 바꾸기
plt.rcParams['scatter.marker'] = '*'

등등...
지금의 설정이 어떤지 보고싶으면 print(~)해서 확인하면 된다

 

다만 rcParams를 통해 설정된 기본값보다 우선시되는 것은

그래프를 그리는 과정에서 직접 설정한 값이다. 

#기본설정
plt.rcParams['scatter.marker'] = '*'

#그리는 과정에서 직접설정
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1, marker='+')

기본 설정이 별모양 마커라도 그래프를 그릴 때 마커를 +로 설정하면 +로 출력된다. 

 

3. subplot

하나의 피겨 객체 안에 여러개의 서브플롯을 담을 수 있다. 

서브플롯은 Axes 클래스의 객체이며, 두 개 이상의 축을 포함한다. 

즉, 기본적으로 여러개의 서브플롯은 2차원의 행렬 평면에 놓이며, 각 플롯이 하나의 요소가 되는 것이다. 

 

subplot() 함수를 통해 서브플롯을 정의할 수 있으며 괄호 안에 행, 열을 지정하여 그래프를 그릴 수 있다. 

fig, axs = plt.subplots(1, 2, figsize=(10, 4))
#여러 plot을 하나의 figure안에서 다루기에 fig, axs를 모두 정의해서 한번에 관리하도록 한다. 
#subplots(행, 열)로 설정하며 여러개의 그래프를 원하는 행렬의 모양으로 배치할 수 있다. 
#subplots(3)이면 기본적으로 행이 3개, 열이 1개인 행렬이다. 

axs[0].scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
axs[0].set_title('scatter plot')
axs[0].set_xlabel('number of books')
axs[0].set_ylabel('borrow count')

axs[1].hist(ns_book7['대출건수'], bins=100)
axs[1].set_title('histogram')
axs[1].set_yscale('log')
axs[1].set_xlabel('borrow count')
axs[1].set_ylabel('frequency')

#각 그래프는 그 위치에 맞게 axs의 인덱스를 활용하여 위치를 정한뒤, 설정한다.

 

+) 두 개 이상의 행,열을 가진 subplot을 출력한다면 axs의 인덱스만 잘 처리해주면 된다. 

fig, axs = plt.subplots(2, 2, figsize=(10, 8))

axs[0,1].scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
axs[0,1].set_title('scatter plot')

axs[1][1].hist(ns_book7['대출건수'], bins=100)
axs[1][1].set_title('histogram')

어제 포스팅을 끝내고 싶었지만... 시험을 치고 난 뒤라 집중력이 흐려져 중간에 멈추고,

오늘(일요일) 늦잠자고 일어나 영화를 보러 갔습니다

요즘 하고 있는 좀비딸 영화를 보러갔는데 웃음과 울음을 동시에 챙긴 영화였어요

무대인사 회차로 예매해서 배우분들도 보고 왔습니당

 

그리고 바로 하면 됐었는데...

새로운 재밌는 게임을 찾았어요

<데이브 더 다이버>

지금 닌텐도 e숍에서 할인 중이니 관심있으신 분들은... 구매하시고 즐겜하세욯ㅎㅎ

저는 할 만큼 하고 이제 진짜 시작합니다


05-2. 선 그래프와 막대 그래프 그리기

 

이 소단원의 목표는 제목에서 알 수 있듯이 선 그래프와 막대 그래프를 그리는 것입니다.

 

1. df에서 그래프를 그릴 수 있도록 자료 뽑기

value_counts() : df에서 고유한 값의 등장 횟수 계산하기

count_by_year = ns_book7['발행년도'].value_counts()
#결과는 판다스 시리즈 객체로 출력
#'발행년도'가 인덱스가 되고, counts횟수가 값이 되는 시리즈 형태로 출력

 

+)

그려야 하는 그래프에 따라 df에 있는 값을 변형하여 인덱스로 사용해야 하는 경우

새로운 함수를 정의하고, apply()함수를 이용하여 모든 열에 적용한다. 

count_by_subject = ns_book7['주제분류번호'].apply(kdc_1st_char).value_counts()
count_by_subject

 

* 인덱스의 정렬이 필요할 경우 

df.sort_index() - 기본 정렬은 오름차순

df.sort_index(ascending=False) - 내림차순

 

2. 선 그래프 그리기

plot() : 선 그래프

plt.plot(count_by_year.index, count_by_year.values)
#x축, y축에 들어갈 값을 따로따로 넣어도 됨

plt.plot(count_by_year, marker='.', linestyle=':', color='red')
#시리즈 객체일 경우 한번에 넣어도 됨(인덱스 - x축, 값 -y축)

 

- 선 그래프의 기타 설정 매개변수

1) linestyle 

실선 '-' , 점선 ':' , 쇄선 '-.' , 파선 '--'

 

2) color

'16진수 컬러코드' 또는 'red'와 같은 색깔 이름, 'r' 처럼 약자도 가능

 

3) marker

마커모양, 기본적으로 '.' , '+' , '*' , '^' 등 사용

 

=> 마커, 선모양, 색깔을 하나의 문자열로 합쳐서 표현 가능

plt.plot(count_by_year, '*-g')
#마커*,실선,초록색

 

4)xticks(), yticks()

- x,y축 눈금을 지정하는 함수

괄호 안에 리스트를 입력하면 해당 값을 모두 숫자로 표시해줌

plt.xticks(range(1947, 2030, 10))
#10간격으로 눈금표시

 

5)annotate() 

- 그래프에 값을 표시하는 함수

그래프에 특정 위치에 해당 위치에 맞는 값을 표시

for idx, val in count_by_year[::5].items():
    plt.annotate(val, (idx, val))
    #(나타낼 숫자, (나타낼 위치 좌표))
    
 plt.annotate(val, (idx, val), xytext=(idx+1, val+10))
 #textcoords 설정을 따로 하지 않으면, 기존 좌표에서의 상대적 위치를 설정.
 #textcoords의 기본 설정이 data이기 때문에, 
 #이 매개변수에 대한 설정 없이 (2,2) 이런 식으로 적으면 고정된 특정 좌표로 알아들음
 
 plt.annotate(val, (idx, val), xytext=(2, 2), textcoords='offset points')
 #textcoords를 따로 설정해주면 xytext는 상대적으로 이동하는 양을 나타냄, 기준-point

*items() : 시리즈 객체에서 사용하면 인덱스와 값을 튜플로 출력

                 딕셔너리에서 사용하면 키와 값을 튜플로 출력

*슬라이싱을 활용해서 5간격으로 떨어진 값들을 그래프에 표시

** 텍스트의 위치를 조절하는 매개변수 xytext, textcoords

     -xytext : annotate의 좌표에서 더 변하는 부분을 표시

     -textcoord : xytext와 함께 쓰여서 지정한 이동량의 기준을 설정 'offset points' or 'offset pixels'

 

3. 막대그래프 그리기

bar() : 막대그래프

*시리즈 객체로 한번에 표현 불가, xy값 명시 필요
plt.bar(count_by_subject.index, count_by_subject.values, width=0.7, color='blue')

 

- 막대 그래프의 기타 설정 매개변수

1) width : 막대 두께조절

                 기본값은 0.8

 

2) annotate() 함수의 매개변수

 - ha : 텍스트 위치 조절(left,center,right)

          기본값은 'right'로 막대그래프의 오른쪽 끝에서 텍스트가 시작. 

- fontsize : 텍스트 사이즈 조절

 

 

 

*barh() : 가로 막대 그래프

-> width -> height, annotate 함수에 좌표도 x,y반대로 작성

**annotate의 매개변수 ha -> va로 변경

plt.barh(count_by_subject.index, count_by_subject.values, height=0.7, color='blue')
#barh함수에 x,y값은 그대로 바꾸지 않고 넣음

for idx, val in count_by_subject.items():
    plt.annotate(val, (val, idx), xytext=(2, 0), textcoords='offset points',
                 fontsize=8, va='center', color='green')
                 #(idx,val) -> (val,idx)

 

 

[기본과제]

 

[추가과제]

 

 

드디어 마쳤습니다!

지각을 밥먹듯이 하네요

이번 주는 좀 제 시간 안에 제출하나 했더니...

 

저는 이제 다시 게임하러 가보겠습니다ㅎㅎ

다음주에는 정시제출하기를(제발)