코딩하는 해맑은 거북이

[데이터시각화] Text 본문

Data Analysis & Viz

[데이터시각화] Text

#CJE 2023. 3. 22.
본 게시물의 내용은 '부스트캠프 AI Tech - Data Visualization(안수빈)' 강의를 듣고 작성하였다.
해당 글은 아래의 2가지를 다룬다.
🍀 Matplotlib에서 Text
   🔷 Anatomy of a Figure (Text Ver.)
🍀 Text Properties
   🔷 Font Components
   🔷 Details
   🔷 Alignment
   🔷 bbox
   🚩 Student Score Dataset
   🔷 Title & Legend
   🔷 Ticks & Text
   🔷 Annotate

 

🍀 Matplotlib에서 Text

- Visual representation들이 줄 수 없는 많은 설명을 추가해줄 수도 있고, 잘못된 전달에서 생기는 오해를 방지할 수도 있다.

- 하지만 Text를 과하게 사용한다면 오히려 이해를 방해할 수도 있음

 

🔷 Anatomy of a Figure (Text Ver.) 

  • Title : 가장 큰 주제를 설명
  • Label : 축에 해당하는 데이터 정보를 제공
  • Tick Label : 축에 눈금을 사용하여 스케일 정보를 추가
  • Legend : 한 그래프에서 2개 이상의 서로 다른 데이터를 분류하기 위해서 사용하는 보조 정보
  • Annotation(Text) : 그 외의 시각화에 대한 설명을 추가
import numpy as np
import pandas as pd
import matplotlib as mpl 
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

fig.suptitle('Figure Title')

ax.plot([1, 3, 2], label='legend')
ax.legend()

ax.set_title('Ax Title')
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

ax.text(x=1,y=2, s='Text')  # 좌표
fig.text(0.5, 0.6, s='Figure Text') # 비율

plt.show()

 

🍀 Text Properties : 참고자료

🔷 Font Components

  • family : 글씨체
  • size or fontsize : 폰트크기
  • style or fontstyle : 폰트스타일
  • weight or fontweight : 폰트굵기

fig, ax = plt.subplots()
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

ax.text(x=0.5, y=0.5, s='Text\nis Important',
        fontsize=20,
        fontweight='bold',
        fontfamily='serif',
       )


plt.show()

 

 

🔷 Details

커스텀 할 수 있는 요소들

  • color : 색깔
  • linespacing : 라인 간 간격
  • backgroundcolor : 배경색깔
  • alpha : 투명도
  • zorder : 순서 (ppt에서 제일 앞으로 순서설정 같은거)
  • visible : 보일지, 말지
fig, ax = plt.subplots()
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

ax.text(x=0.5, y=0.5, s='Text\nis Important',
        fontsize=20,
        fontweight='bold',
        fontfamily='serif',
        color='royalblue',
        linespacing=2,
        backgroundcolor='lightgray',
        alpha=0.5
       )


plt.show()

 

🔷 Alignment

정렬과 관련된 요소들을 조정할 수 있다

  • ha : horizontal alignment (수평조절) : 수평으로 글자 시작점 설정 'left' | 'right' | 'center'
  • va : vertical alignment (수직조정) : 수직으로 글자 시작점 설정 'top' | 'bottom' | 'center' | 'baseline'
  • rotation : angle in degrees | 'vertical' | 'horizontal'
  • multialignment : 글자정렬 : 'left' | 'right' | 'center'
fig, ax = plt.subplots()
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

ax.text(x=0.5, y=0.5, s='Text\nis Important',
        fontsize=20,
        fontweight='bold',
        fontfamily='serif',
        color='royalblue',
        linespacing=2,
        va='center', # top, bottom, center   : 글자 시작점 설정
        ha='center', # left, right, center   : 글자 시작점 설정
        rotation='vertical'
       )


plt.show()

fig, ax = plt.subplots()
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

ax.text(x=0.5, y=0.5, s='Text\nis Important',
        fontsize=20,
        fontweight='bold',
        fontfamily='serif',
        color='royalblue',
        linespacing=2,
        va='center', # top, bottom, center   : 글자 시작점 설정
        ha='center', # left, right, center   : 글자 시작점 설정
        rotation=45  # 각도만큼 기울어짐
       )


plt.show()

fig, ax = plt.subplots()
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

ax.text(x=0.5, y=0.5, s='Text\nis Important',
        fontsize=20,
        fontweight='bold',
        fontfamily='serif',
        color='royalblue',
        linespacing=2,
        multialignment='right'
       )


plt.show()

 

 

🔷 bbox : 참고자료

fig, ax = plt.subplots()
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

ax.text(x=0.5, y=0.5, s='Text\nis Important',
        fontsize=20,
        fontweight='bold',
        fontfamily='serif',
        color='black',
        linespacing=2,
        va='center', # top, bottom, center
        ha='center', # left, right, center
        rotation='horizontal', # vertical?
        bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.4)
       )


plt.show()

fig, ax = plt.subplots()
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

ax.text(x=0.5, y=0.5, s='Text\nis Important',
        fontsize=20,
        fontweight='bold',
        fontfamily='serif',
        color='black',
        linespacing=2,
        va='center', # top, bottom, center
        ha='center', # left, right, center
        rotation='horizontal', # vertical?
        bbox=dict(boxstyle='round', facecolor='wheat', ec='red', alpha=0.4)  # ec : edgecolor
       )


plt.show()

 

 

🚩 Student Score Dataset

student = pd.read_csv('./StudentsPerformance.csv')
student.head()

fig = plt.figure(figsize=(9, 9))
ax = fig.add_subplot(111, aspect=1)

for g, c in zip(['male', 'female'], ['royalblue', 'tomato']):
    student_sub = student[student['gender']==g]
    ax.scatter(x=student_sub ['math score'], y=student_sub ['reading score'],
               c=c,
               alpha=0.5, 
               label=g)
    
ax.set_xlim(-3, 102)
ax.set_ylim(-3, 102)

ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

ax.set_xlabel('Math Score')
ax.set_ylabel('Reading Score')

ax.set_title('Score Relation') 
ax.legend()   

plt.show()

 

🔷 Title & Legend

  • 제목의 위치 조정하기 : ax.set_title(..., loc='left')
  • 범례에 제목(title), 그림자 달기(shadow), 위치 조정하기(loc | bbox_to_anchor) : ax.legend(..)
fig = plt.figure(figsize=(9, 9))
ax = fig.add_subplot(111, aspect=1)

for g, c in zip(['male', 'female'], ['royalblue', 'tomato']):
    student_sub = student[student['gender']==g]
    ax.scatter(x=student_sub ['math score'], y=student_sub ['reading score'],
               c=c,
               alpha=0.5, 
               label=g)
    
ax.set_xlim(-3, 102)
ax.set_ylim(-3, 102)

ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

ax.set_xlabel('Math Score', 
              fontweight='semibold')
ax.set_ylabel('Reading Score', 
              fontweight='semibold')

ax.set_title('Score Relation', 
             loc='left', va='bottom',
             fontweight='bold', fontsize=15
            )   # loc : 위치, 

ax.legend(
    title='Gender',
    shadow=True,    # 그림자
    labelspacing=1.2,   # 범례 속성 간 간격
#     loc='lower right'   # 범례 위치
#     bbox_to_anchor=[1.2, 0.5]   # 범례 위치 : 비율사용
    ncol=2    # 열 갯수
)

plt.show()

 

 

🔷 Ticks & Text

  • tick을 없애거나( ax.set_yticks([]) ) 조정하는 방법( ax.set_xticks(리스트) )
  • text의 alignment가 필요한 이유 : 아래예제에선 중앙에 위치와 크기를 키워 가독성UP
def score_band(x):
    tmp = (x+9)//10
    if tmp <= 1: 
        return '0 - 10'
    return f'{tmp*10-9} - {tmp*10}'

student['math-range'] = student['math score'].apply(score_band)
student['math-range'].value_counts().sort_index()

math_grade = student['math-range'].value_counts().sort_index()

fig, ax = plt.subplots(1, 1, figsize=(11, 7))
ax.bar(math_grade.index, math_grade,
       width=0.65, 
       color='royalblue',
       linewidth=1,
       edgecolor='black'
      )

ax.margins(0.07)
plt.show()

math_grade = student['math-range'].value_counts().sort_index()

fig, ax = plt.subplots(1, 1, figsize=(11, 7))
ax.bar(math_grade.index, math_grade,
       width=0.65, 
       color='royalblue',
       linewidth=1,
       edgecolor='black'
      )

ax.margins(0.01, 0.1)
ax.set(frame_on=False)  # 4변의 테두리 없애줌
ax.set_yticks([])   # y축이 사라짐
ax.set_xticks(np.arange(len(math_grade)))
ax.set_xticklabels(math_grade.index, fontsize=11)

ax.set_title('Math Score Distribution', fontsize=14, fontweight='semibold')

for idx, val in math_grade.iteritems():
    ax.text(x=idx, y=val+3, s=val,
            va='bottom', ha='center',
            fontsize=11, fontweight='semibold'
           )

plt.show()

 

 

🔷 Annotate

  • 화살표 사용하기
fig = plt.figure(figsize=(9, 9))
ax = fig.add_subplot(111, aspect=1)

i = 13

ax.scatter(x=student['math score'], y=student['reading score'],
           c='lightgray',
           alpha=0.9, zorder=5)
    
ax.scatter(x=student['math score'][i], y=student['reading score'][i],
           c='tomato',
           alpha=1, zorder=10)    
    
ax.set_xlim(-3, 102)
ax.set_ylim(-3, 102)

ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

ax.set_xlabel('Math Score')
ax.set_ylabel('Reading Score')

ax.set_title('Score Relation') 

# x축과 평행한 선
ax.plot([-3, student['math score'][i]], [student['reading score'][i]]*2,
        color='gray', linestyle='--',
        zorder=8)

# y축과 평행한 선
ax.plot([student['math score'][i]]*2, [-3, student['reading score'][i]],
       color='gray', linestyle='--',
       zorder=8)

bbox = dict(boxstyle="round", fc='wheat', pad=0.2)
arrowprops = dict(
    arrowstyle="->")

ax.annotate(text=f'This is #{i} Studnet',
            xy=(student['math score'][i], student['reading score'][i]),
            xytext=[80, 40],
            bbox=bbox,
            arrowprops=arrowprops,
            zorder=9
           )

plt.show()

 

 

'Data Analysis & Viz' 카테고리의 다른 글

[데이터시각화] Facet  (0) 2023.03.22
[데이터시각화] Color  (0) 2023.03.22
[데이터시각화] Scatter Plot  (0) 2023.03.22
[데이터시각화] Line Plot  (0) 2023.03.22
[데이터시각화] Bar Plot  (0) 2023.03.22
Comments