🚴‍♂️
TIL
  • MAIN
  • : TIL?
  • : WIL
  • : Plan
  • : Retrospective
    • 21Y
      • Wait a moment!
      • 9M 2W
      • 9M1W
      • 8M4W
      • 8M3W
      • 8M2W
      • 8M1W
      • 7M4W
      • 7M3W
      • 7M2W
      • 7M1W
      • 6M5W
      • 1H
    • 새사람 되기 프로젝트
      • 2회차
      • 1회차
  • TIL : ML
    • Paper Analysis
      • BERT
      • Transformer
    • Boostcamp 2st
      • [S]Data Viz
        • (4-3) Seaborn 심화
        • (4-2) Seaborn 기초
        • (4-1) Seaborn 소개
        • (3-4) More Tips
        • (3-3) Facet 사용하기
        • (3-2) Color 사용하기
        • (3-1) Text 사용하기
        • (2-3) Scatter Plot 사용하기
        • (2-2) Line Plot 사용하기
        • (2-1) Bar Plot 사용하기
        • (1-3) Python과 Matplotlib
        • (1-2) 시각화의 요소
        • (1-1) Welcome to Visualization (OT)
      • [P]MRC
        • (2강) Extraction-based MRC
        • (1강) MRC Intro & Python Basics
      • [P]KLUE
        • (5강) BERT 기반 단일 문장 분류 모델 학습
        • (4강) 한국어 BERT 언어 모델 학습
        • [NLP] 문장 내 개체간 관계 추출
        • (3강) BERT 언어모델 소개
        • (2강) 자연어의 전처리
        • (1강) 인공지능과 자연어 처리
      • [U]Stage-CV
      • [U]Stage-NLP
        • 7W Retrospective
        • (10강) Advanced Self-supervised Pre-training Models
        • (09강) Self-supervised Pre-training Models
        • (08강) Transformer (2)
        • (07강) Transformer (1)
        • 6W Retrospective
        • (06강) Beam Search and BLEU score
        • (05강) Sequence to Sequence with Attention
        • (04강) LSTM and GRU
        • (03강) Recurrent Neural Network and Language Modeling
        • (02강) Word Embedding
        • (01강) Intro to NLP, Bag-of-Words
        • [필수 과제 4] Preprocessing for NMT Model
        • [필수 과제 3] Subword-level Language Model
        • [필수 과제2] RNN-based Language Model
        • [선택 과제] BERT Fine-tuning with transformers
        • [필수 과제] Data Preprocessing
      • Mask Wear Image Classification
        • 5W Retrospective
        • Report_Level1_6
        • Performance | Review
        • DAY 11 : HardVoting | MultiLabelClassification
        • DAY 10 : Cutmix
        • DAY 9 : Loss Function
        • DAY 8 : Baseline
        • DAY 7 : Class Imbalance | Stratification
        • DAY 6 : Error Fix
        • DAY 5 : Facenet | Save
        • DAY 4 : VIT | F1_Loss | LrScheduler
        • DAY 3 : DataSet/Lodaer | EfficientNet
        • DAY 2 : Labeling
        • DAY 1 : EDA
        • 2_EDA Analysis
      • [P]Stage-1
        • 4W Retrospective
        • (10강) Experiment Toolkits & Tips
        • (9강) Ensemble
        • (8강) Training & Inference 2
        • (7강) Training & Inference 1
        • (6강) Model 2
        • (5강) Model 1
        • (4강) Data Generation
        • (3강) Dataset
        • (2강) Image Classification & EDA
        • (1강) Competition with AI Stages!
      • [U]Stage-3
        • 3W Retrospective
        • PyTorch
          • (10강) PyTorch Troubleshooting
          • (09강) Hyperparameter Tuning
          • (08강) Multi-GPU 학습
          • (07강) Monitoring tools for PyTorch
          • (06강) 모델 불러오기
          • (05강) Dataset & Dataloader
          • (04강) AutoGrad & Optimizer
          • (03강) PyTorch 프로젝트 구조 이해하기
          • (02강) PyTorch Basics
          • (01강) Introduction to PyTorch
      • [U]Stage-2
        • 2W Retrospective
        • DL Basic
          • (10강) Generative Models 2
          • (09강) Generative Models 1
          • (08강) Sequential Models - Transformer
          • (07강) Sequential Models - RNN
          • (06강) Computer Vision Applications
          • (05강) Modern CNN - 1x1 convolution의 중요성
          • (04강) Convolution은 무엇인가?
          • (03강) Optimization
          • (02강) 뉴럴 네트워크 - MLP (Multi-Layer Perceptron)
          • (01강) 딥러닝 기본 용어 설명 - Historical Review
        • Assignment
          • [필수 과제] Multi-headed Attention Assignment
          • [필수 과제] LSTM Assignment
          • [필수 과제] CNN Assignment
          • [필수 과제] Optimization Assignment
          • [필수 과제] MLP Assignment
      • [U]Stage-1
        • 1W Retrospective
        • AI Math
          • (AI Math 10강) RNN 첫걸음
          • (AI Math 9강) CNN 첫걸음
          • (AI Math 8강) 베이즈 통계학 맛보기
          • (AI Math 7강) 통계학 맛보기
          • (AI Math 6강) 확률론 맛보기
          • (AI Math 5강) 딥러닝 학습방법 이해하기
          • (AI Math 4강) 경사하강법 - 매운맛
          • (AI Math 3강) 경사하강법 - 순한맛
          • (AI Math 2강) 행렬이 뭐예요?
          • (AI Math 1강) 벡터가 뭐예요?
        • Python
          • (Python 7-2강) pandas II
          • (Python 7-1강) pandas I
          • (Python 6강) numpy
          • (Python 5-2강) Python data handling
          • (Python 5-1강) File / Exception / Log Handling
          • (Python 4-2강) Module and Project
          • (Python 4-1강) Python Object Oriented Programming
          • (Python 3-2강) Pythonic code
          • (Python 3-1강) Python Data Structure
          • (Python 2-4강) String and advanced function concept
          • (Python 2-3강) Conditionals and Loops
          • (Python 2-2강) Function and Console I/O
          • (Python 2-1강) Variables
          • (Python 1-3강) 파이썬 코딩 환경
          • (Python 1-2강) 파이썬 개요
          • (Python 1-1강) Basic computer class for newbies
        • Assignment
          • [선택 과제 3] Maximum Likelihood Estimate
          • [선택 과제 2] Backpropagation
          • [선택 과제 1] Gradient Descent
          • [필수 과제 5] Morsecode
          • [필수 과제 4] Baseball
          • [필수 과제 3] Text Processing 2
          • [필수 과제 2] Text Processing 1
          • [필수 과제 1] Basic Math
    • 딥러닝 CNN 완벽 가이드 - Fundamental 편
      • 종합 실습 2 - 캐글 Plant Pathology(나무잎 병 진단) 경연 대회
      • 종합 실습 1 - 120종의 Dog Breed Identification 모델 최적화
      • 사전 훈련 모델의 미세 조정 학습과 다양한 Learning Rate Scheduler의 적용
      • Advanced CNN 모델 파헤치기 - ResNet 상세와 EfficientNet 개요
      • Advanced CNN 모델 파헤치기 - AlexNet, VGGNet, GoogLeNet
      • Albumentation을 이용한 Augmentation기법과 Keras Sequence 활용하기
      • 사전 훈련 CNN 모델의 활용과 Keras Generator 메커니즘 이해
      • 데이터 증강의 이해 - Keras ImageDataGenerator 활용
      • CNN 모델 구현 및 성능 향상 기본 기법 적용하기
    • AI School 1st
    • 현업 실무자에게 배우는 Kaggle 머신러닝 입문
    • 파이썬 딥러닝 파이토치
  • TIL : Python & Math
    • Do It! 장고+부트스트랩: 파이썬 웹개발의 정석
      • Relations - 다대다 관계
      • Relations - 다대일 관계
      • 템플릿 파일 모듈화 하기
      • TDD (Test Driven Development)
      • template tags & 조건문
      • 정적 파일(static files) & 미디어 파일(media files)
      • FBV (Function Based View)와 CBV (Class Based View)
      • Django 입문하기
      • 부트스트랩
      • 프론트엔드 기초다지기 (HTML, CSS, JS)
      • 들어가기 + 환경설정
    • Algorithm
      • Programmers
        • Level1
          • 소수 만들기
          • 숫자 문자열과 영단어
          • 자연수 뒤집어 배열로 만들기
          • 정수 내림차순으로 배치하기
          • 정수 제곱근 판별
          • 제일 작은 수 제거하기
          • 직사각형 별찍기
          • 짝수와 홀수
          • 체육복
          • 최대공약수와 최소공배수
          • 콜라츠 추측
          • 크레인 인형뽑기 게임
          • 키패드 누르기
          • 평균 구하기
          • 폰켓몬
          • 하샤드 수
          • 핸드폰 번호 가리기
          • 행렬의 덧셈
        • Level2
          • 숫자의 표현
          • 순위 검색
          • 수식 최대화
          • 소수 찾기
          • 소수 만들기
          • 삼각 달팽이
          • 문자열 압축
          • 메뉴 리뉴얼
          • 더 맵게
          • 땅따먹기
          • 멀쩡한 사각형
          • 괄호 회전하기
          • 괄호 변환
          • 구명보트
          • 기능 개발
          • 뉴스 클러스터링
          • 다리를 지나는 트럭
          • 다음 큰 숫자
          • 게임 맵 최단거리
          • 거리두기 확인하기
          • 가장 큰 정사각형 찾기
          • H-Index
          • JadenCase 문자열 만들기
          • N개의 최소공배수
          • N진수 게임
          • 가장 큰 수
          • 124 나라의 숫자
          • 2개 이하로 다른 비트
          • [3차] 파일명 정렬
          • [3차] 압축
          • 줄 서는 방법
          • [3차] 방금 그곡
          • 거리두기 확인하기
        • Level3
          • 매칭 점수
          • 외벽 점검
          • 기지국 설치
          • 숫자 게임
          • 110 옮기기
          • 광고 제거
          • 길 찾기 게임
          • 셔틀버스
          • 단속카메라
          • 표 편집
          • N-Queen
          • 징검다리 건너기
          • 최고의 집합
          • 합승 택시 요금
          • 거스름돈
          • 하노이의 탑
          • 멀리 뛰기
          • 모두 0으로 만들기
        • Level4
    • Head First Python
    • 데이터 분석을 위한 SQL
    • 단 두 장의 문서로 데이터 분석과 시각화 뽀개기
    • Linear Algebra(Khan Academy)
    • 인공지능을 위한 선형대수
    • Statistics110
  • TIL : etc
    • [따배런] Kubernetes
    • [따배런] Docker
      • 2. 도커 설치 실습 1 - 학습편(준비물/실습 유형 소개)
      • 1. 컨테이너와 도커의 이해 - 컨테이너를 쓰는이유 / 일반프로그램과 컨테이너프로그램의 차이점
      • 0. 드디어 찾아온 Docker 강의! 왕초보에서 도커 마스터로 - OT
    • CoinTrading
      • [가상 화폐 자동 매매 프로그램] 백테스팅 : 간단한 테스팅
    • Gatsby
      • 01 깃북 포기 선언
  • TIL : Project
    • Mask Wear Image Classification
    • Project. GARIGO
  • 2021 TIL
    • CHANGED
    • JUN
      • 30 Wed
      • 29 Tue
      • 28 Mon
      • 27 Sun
      • 26 Sat
      • 25 Fri
      • 24 Thu
      • 23 Wed
      • 22 Tue
      • 21 Mon
      • 20 Sun
      • 19 Sat
      • 18 Fri
      • 17 Thu
      • 16 Wed
      • 15 Tue
      • 14 Mon
      • 13 Sun
      • 12 Sat
      • 11 Fri
      • 10 Thu
      • 9 Wed
      • 8 Tue
      • 7 Mon
      • 6 Sun
      • 5 Sat
      • 4 Fri
      • 3 Thu
      • 2 Wed
      • 1 Tue
    • MAY
      • 31 Mon
      • 30 Sun
      • 29 Sat
      • 28 Fri
      • 27 Thu
      • 26 Wed
      • 25 Tue
      • 24 Mon
      • 23 Sun
      • 22 Sat
      • 21 Fri
      • 20 Thu
      • 19 Wed
      • 18 Tue
      • 17 Mon
      • 16 Sun
      • 15 Sat
      • 14 Fri
      • 13 Thu
      • 12 Wed
      • 11 Tue
      • 10 Mon
      • 9 Sun
      • 8 Sat
      • 7 Fri
      • 6 Thu
      • 5 Wed
      • 4 Tue
      • 3 Mon
      • 2 Sun
      • 1 Sat
    • APR
      • 30 Fri
      • 29 Thu
      • 28 Wed
      • 27 Tue
      • 26 Mon
      • 25 Sun
      • 24 Sat
      • 23 Fri
      • 22 Thu
      • 21 Wed
      • 20 Tue
      • 19 Mon
      • 18 Sun
      • 17 Sat
      • 16 Fri
      • 15 Thu
      • 14 Wed
      • 13 Tue
      • 12 Mon
      • 11 Sun
      • 10 Sat
      • 9 Fri
      • 8 Thu
      • 7 Wed
      • 6 Tue
      • 5 Mon
      • 4 Sun
      • 3 Sat
      • 2 Fri
      • 1 Thu
    • MAR
      • 31 Wed
      • 30 Tue
      • 29 Mon
      • 28 Sun
      • 27 Sat
      • 26 Fri
      • 25 Thu
      • 24 Wed
      • 23 Tue
      • 22 Mon
      • 21 Sun
      • 20 Sat
      • 19 Fri
      • 18 Thu
      • 17 Wed
      • 16 Tue
      • 15 Mon
      • 14 Sun
      • 13 Sat
      • 12 Fri
      • 11 Thu
      • 10 Wed
      • 9 Tue
      • 8 Mon
      • 7 Sun
      • 6 Sat
      • 5 Fri
      • 4 Thu
      • 3 Wed
      • 2 Tue
      • 1 Mon
    • FEB
      • 28 Sun
      • 27 Sat
      • 26 Fri
      • 25 Thu
      • 24 Wed
      • 23 Tue
      • 22 Mon
      • 21 Sun
      • 20 Sat
      • 19 Fri
      • 18 Thu
      • 17 Wed
      • 16 Tue
      • 15 Mon
      • 14 Sun
      • 13 Sat
      • 12 Fri
      • 11 Thu
      • 10 Wed
      • 9 Tue
      • 8 Mon
      • 7 Sun
      • 6 Sat
      • 5 Fri
      • 4 Thu
      • 3 Wed
      • 2 Tue
      • 1 Mon
    • JAN
      • 31 Sun
      • 30 Sat
      • 29 Fri
      • 28 Thu
      • 27 Wed
      • 26 Tue
      • 25 Mon
      • 24 Sun
      • 23 Sat
      • 22 Fri
      • 21 Thu
      • 20 Wed
      • 19 Tue
      • 18 Mon
      • 17 Sun
      • 16 Sat
      • 15 Fri
      • 14 Thu
      • 13 Wed
      • 12 Tue
      • 11 Mon
      • 10 Sun
      • 9 Sat
      • 8 Fri
      • 7 Thu
      • 6 Wed
      • 5 Tue
      • 4 Mon
      • 3 Sun
      • 2 Sat
      • 1 Fri
  • 2020 TIL
    • DEC
      • 31 Thu
      • 30 Wed
      • 29 Tue
      • 28 Mon
      • 27 Sun
      • 26 Sat
      • 25 Fri
      • 24 Thu
      • 23 Wed
      • 22 Tue
      • 21 Mon
      • 20 Sun
      • 19 Sat
      • 18 Fri
      • 17 Thu
      • 16 Wed
      • 15 Tue
      • 14 Mon
      • 13 Sun
      • 12 Sat
      • 11 Fri
      • 10 Thu
      • 9 Wed
      • 8 Tue
      • 7 Mon
      • 6 Sun
      • 5 Sat
      • 4 Fri
      • 3 Tue
      • 2 Wed
      • 1 Tue
    • NOV
      • 30 Mon
Powered by GitBook
On this page
  • Bar Plot
  • 다양한 Bar Plot
  • Multiple Bar Plot
  • Stacked Bar Plot
  • Overlapped Bar Plot
  • Grouped Bar Plot
  • 정확한 Bar Plot
  • 잉크양 비례 법칙
  • 데이터 정렬하기
  • 적절한 공간 활용
  • 복잡함과 단순함
  • ETC
  • 실습 1-1. Bar Plot 사용하기
  • 1. 기본 Bar Plot
  • 2. 다양한 Bar Plot
  • 3. 정확한 Bar Plot

Was this helpful?

  1. TIL : ML
  2. Boostcamp 2st
  3. [S]Data Viz

(2-1) Bar Plot 사용하기

210811

Previous(2-2) Line Plot 사용하기Next(1-3) Python과 Matplotlib

Last updated 3 years ago

Was this helpful?

Bar Plot

직사각형 막대를 사용하여 데이터의 값을 표현하는 차트/그래프

  • 막대 그래프, bar chart, bar graph의 여러 이름을 가짐

  • 범주에 따른 수치 값을 비교하기에 적합

    • 개별비교, 그룹비교 모두 적합하다

막대의 방향에 따른 분류

  • 수직 : .bar()

    • 기본적으로 사용한다

  • 수평 : .barh()

    • 범주가 많을 때 사용한다

다양한 Bar Plot

Sky = [1, 2, 3, 4, 3]
Pink = [4, 3, 2, 5, 1]

위 두 데이터를 비교하기 위한 여러 방법을 사용할 것임

Multiple Bar Plot

  1. 플롯을 여러 개 그리는 방법

  2. 한 개의 플롯에 동시에 나타내는 방법

    • 쌓아서 표현

    • 겹쳐서 표현

    • 이웃에 배치하여 표현

Stacked Bar Plot

2개 이상의 그룹을 쌓아서 표현하는 bar plot

  • 이 때 각 bar에서 나타나는 그룹의 순서는 유지해야 한다. 그렇지 않으면 혼동을 줄 수 있다.

맨 밑에 bar의 분포는 파악하기 쉽다

  • 그러나 그 외의 분포들은 파악하기 어렵다

    • sky 데이터는 파악하기 쉽지만, pink 데이터는 파악하기 어렵다.

    • 이럴 때는 수치를 annotation 달 것을 추천한다.

  • 2개의 그룹이 positive/negative 라면 축 조정이 가능하다

  • .bar() 에서는 bottom 파라미터를 사용하고 .barh() 에서는 left 파라미터를 사용한다

좀 더 데이터 분포 비교가 원활한 Percentage Stacked Bar Chart 도 있다.

  • 각 bar 마다 퍼센트 수치를 알려주는 annotation이 표기되어 있는 모습

Overlapped Bar Plot

2개 그룹만 비교한다면 겹쳐서 만들 수도 있다.

  • 3개 이상부터는 파악이 어렵기 때문

같은 축을 사용하기 때문에 비교와 구현이 쉽다. 이 때, 투명도를 조정해서 겹치는 부분을 파악해야 한다 또, Bar Plot보다는 Area Plot에서 더 효과적이다.

Grouped Bar Plot

그룹별 범주에 따른 bar를 이웃되게 배치하는 방법이다. Matplotlib 로는 구현이 까다로워서 편하게 사용할 수 있는 Seaborn 을 주로 사용한다.

  • .set_xticks(), .set_xticklabels()

대부분의 Bar Plot은 그룹이 최대 7개 이하일 때 효과적이다. 그 외의 그룹은 ETC로 표현하거나 Pie Chart같은 다른 그래프로 표현해야 한다

정확한 Bar Plot

잉크양 비례 법칙

실제값과 그에 표현되는 그래픽으로 표현되는 잉크 양은 비례해야 한다는 뜻이다. 값이 클수록 그래프를 더 길게 또는 더 넓게 그려야 한다는 뜻

반드시 x축의 시작은 0에서 부터 시작해야 하며, 이 법칙은 대부분의 그래프에서 모두 적용된다.

왼쪽 그래프는 가독성이 좋고 차이를 확연히 느낄 수 있지만 좋은 그래프가 아니다. 보는 이에게 "첫번째 막대가 마지막 막대의 2배 이상인가?" 라는 혼동을 줄 수 있기 때문.

따라서, 오른쪽 그래프처럼 표현해야 하며 만약 비율의 차이를 보여주고 싶다면 y축의 길이를 늘려야 한다.

데이터 정렬하기

Pandas에서는 sort_values() 나 sort_index() 를 사용하여 정렬한다

데이터의 종류에 따라 다음의 기준으로 정렬할 수 있다.

  • 시계열 | 시간순

  • 수치형 | 크기순

  • 순서형 | 범주의 순서대로

  • 명목형 | 범주의 값 따라 정렬

그렇지만, 정해진 기준은 없으며 여러가지 기준으로 정렬할 수 있으며 이를 통해 패턴을 발견할 수도 있다. 대시보드에서는 Interactive로 제공하는 것이 유용하다

적절한 공간 활용

여백과 공간을 조정하면 가독성이 높아진다. Matplotlib의 bar plot은 ax에 꽉 차서 답답한 경향이 있는데 다음과 같은 방법으로 조정할 수 있다.

  • X/Y axis Limit : .set_xlim(), .set_ylim()

    • x축과 y축의 범위를 설정한다

    • 인자에는 최솟값과 최댓값이 들어간다

  • Spines : .spines[spine].set_visible()

  • Gap(width)

    • 기본으로 0.8의 값을 가지고 있다

    • 1의 값을 가지면 히스토그램 모양이 된다

    • 보통 0.6에서 0.7을 주면 가독성이 높아진다

  • Legend : .legend()

    • 범위를 어디다 둘 것인가

  • Margin : .margins()

복잡함과 단순함

필요없는 복잡함은 안된다.

  • 사람의 인지는 2D에 최적화되어있다.

  • 3D로 보여주려면 실제로 3D 회전이 가능하게 해야한다.

  • 직사각형이 아닌 다른 형태의 bar는 지양하라

    • 그림자도 없어야 한다

Grid

  • 격자라는 것은 데이터가 정확하게 어떤 값인지 보조적으로 전달하는 역할

    • 데이터의 분포와 비율 등의 큰틀에서 추세를 파악할 때는 격자를 빼는것이 좋다.

ETC

오차 막대를 추가하여 Uncertainty 정보를 추가 가능하다. (errorbar)

Bar 사이 Gap이 0이라면 히스토그램을 사용한다

  • .hist() 를 사용하면 되고 연속된 느낌을 줄 수 있다.

다양한 텍스트를 사용할 수 있다

  • 제목 : .set_title()

  • 라벨 : .set_xlabel(), .set_ylabel()

실습 1-1. Bar Plot 사용하기

1. 기본 Bar Plot

  • bar() : 기본적인 bar plot

  • barh() : horizontal bar plot

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

x와 y를 5개 정도로 세팅해서 예시 플롯을 만들어보겠습니다.

fig, axes = plt.subplots(1, 2, figsize=(12, 7))

x = list('ABCDE')
y = np.array([1, 2, 3, 4, 5])

axes[0].bar(x, y)
axes[1].barh(x, y)

plt.show()
# 강의에서 다루지는 않았지만 막대 그래프의 색은 
# 다음과 같이 변경을 전체로 하거나, 개별로 할 수도 있습니다. 
# 개별로 할 때는 막대 개수와 같이 색을 리스트로 전해야 합니다.
# 색에 대해 구체적인 내용은 3차트의 요소-2색에서 다룹니다.

fig, axes = plt.subplots(1, 2, figsize=(12, 7))

x = list('ABCDE')
y = np.array([1, 2, 3, 4, 5])

clist = ['blue', 'gray', 'gray', 'gray', 'red']
color = 'green'
axes[0].bar(x, y, color=clist)
axes[1].barh(x, y, color=color)

plt.show()

2. 다양한 Bar Plot

2-0. 데이터 준비하기

이제 교육용 데이터셋으로 막대 그래프를 사용해보겠습니다.

  • 1000명 학생 데이터

  • feature에 대한 정보는 head(), describe(), info() 등으로 확인하고

  • unique(), value_counts() 등으로 종류나 큰 분포 확인

  • feautre들

    • 성별 : female / male

    • 인종민족 : group A, B, C, D, E

    • 부모님 최종 학력 : 고등학교 졸업, 전문대, 학사 학위, 석사 학위, 2년제 졸업

    • 점심 : standard와 free/reduced

    • 시험 예습 : none과 completed

    • 수학, 읽기, 쓰기 성적 (0~100)

student = pd.read_csv('./exams.csv')
student.sample(5)
  • 데이터를 살필 때는 .head() 로도 할 수 있다. 하지만 보통 데이터는 순서가 있기 때문에 편향적인 데이터를 볼 가능성이 있어서 .sample() 을 쓰는 것이 좋다

gender

race/ethnicity

parental level of education

lunch

test preparation course

math score

reading score

writing score

437

male

group B

associate's degree

free/reduced

none

90

81

75

25

female

group B

bachelor's degree

free/reduced

none

61

74

69

317

female

group D

associate's degree

standard

completed

85

92

96

145

female

group B

some high school

free/reduced

completed

53

53

66

676

female

group E

some college

standard

none

71

76

69

student.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 8 columns):
 #   Column                       Non-Null Count  Dtype 
---  ------                       --------------  ----- 
 0   gender                       1000 non-null   object
 1   race/ethnicity               1000 non-null   object
 2   parental level of education  1000 non-null   object
 3   lunch                        1000 non-null   object
 4   test preparation course      1000 non-null   object
 5   math score                   1000 non-null   int64 
 6   reading score                1000 non-null   int64 
 7   writing score                1000 non-null   int64 
dtypes: int64(3), object(5)
memory usage: 62.6+ KB

각 컬럼의 데이터 타입을 보며 범주형인지 수치형인지 파악할 수 있다. 또 Null 값이 있는지도 알 수 있다.

student.describe(include='all')

gender

race/ethnicity

parental level of education

lunch

test preparation course

math score

reading score

writing score

count

1000

1000

1000

1000

1000

1000.000000

1000.000000

1000.000000

unique

2

5

6

2

2

NaN

NaN

NaN

top

male

group C

some college

standard

none

NaN

NaN

NaN

freq

526

353

242

673

655

NaN

NaN

NaN

mean

NaN

NaN

NaN

NaN

NaN

67.595000

69.865000

68.812000

std

NaN

NaN

NaN

NaN

NaN

15.030066

14.303054

14.845641

min

NaN

NaN

NaN

NaN

NaN

23.000000

23.000000

24.000000

25%

NaN

NaN

NaN

NaN

NaN

58.000000

60.000000

58.000000

50%

NaN

NaN

NaN

NaN

NaN

67.000000

70.000000

69.000000

75%

NaN

NaN

NaN

NaN

NaN

79.000000

80.000000

79.000000

max

NaN

NaN

NaN

NaN

NaN

100.000000

100.000000

100.000000

그룹에 따른 정보를 시각화해봅시다.

성별에 따른 race/ethincity 분포

코드로는 다음과 같이 쉽게 구할 수 있습니다.

group = student.groupby('gender')['race/ethnicity'].value_counts().sort_index()
display(group)
print(student['gender'].value_counts())
gender  race/ethnicity
female  group A            36
        group B            86
        group C           167
        group D           123
        group E            62
male    group A            31
        group B            95
        group C           186
        group D           126
        group E            88
Name: race/ethnicity, dtype: int64

male      526
female    474
Name: gender, dtype: int64

sort_index() 를 하지 않으면 value_counts() 순으로 정렬이 되서 깔끔하지 않을 수 있다.

2-1. Multiple Bar Plot

우선 기본적으로 그려보겠습니다.

fig, axes = plt.subplots(1, 2, figsize=(15, 7))
axes[0].bar(group['male'].index, group['male'], color='royalblue')
axes[1].bar(group['female'].index, group['female'], color='tomato')
plt.show()

위 그래프를 보면 분포가 비슷해 보이지만 y축을 잘 보면 수치가 다른 것을 알 수 있다. matplotlib는 이렇게 그래프를 꽉차게 보여주는 것이 기본이다.

각 barplot은 자체적으로 y 범위를 맞추기에 좀 더 y축의 범위를 공유할 수 있습니다.

방법1은 subplot을 만들 때, sharey 파라미터를 사용하는 방법입니다.

fig, axes = plt.subplots(1, 2, figsize=(15, 7), sharey=True)
axes[0].bar(group['male'].index, group['male'], color='royalblue')
axes[1].bar(group['female'].index, group['female'], color='tomato')
plt.show()

방법2는 y축 범위를 개별적으로 조정하는 방법입니다. 이렇게 할 때는 반복문을 사용하여 조정하는 방법을 선호합니다.

fig, axes = plt.subplots(1, 2, figsize=(15, 7))
axes[0].bar(group['male'].index, group['male'], color='royalblue')
axes[1].bar(group['female'].index, group['female'], color='tomato')

for ax in axes:
    ax.set_ylim(0, 200)
    
plt.show()

Group간의 비교가 어렵다는 단점이 있습니다.

2-2. Stacked Bar Plot

쌓아서 보면 그룹 A, B, C, D, E에 대한 전체 비율은 알기 쉽습니다.

bottom 파라미터를 사용해서 아래 공간을 비워둘 수 있습니다.

fig, axes = plt.subplots(1, 2, figsize=(15, 7))

group_cnt = student['race/ethnicity'].value_counts().sort_index()
axes[0].bar(group_cnt.index, group_cnt, color='darkgray')
axes[1].bar(group['male'].index, group['male'], color='royalblue')
axes[1].bar(group['female'].index, group['female'], bottom=group['male'], color='tomato')

for ax in axes:
    ax.set_ylim(0, 350)
    
plt.show()

여자의 비율 분포를 비교하기 어렵다는 단점이 있기 때문에 여자와 남자의 순서를 바꿀 수 있는 Interactive 한 기능을 제공하는 것이 중요하다

2-3. Percentage Stacked Bar Plot

좀 더 advanced한 테크닉을 사용한다면 다음과 같습니다.

fig, ax = plt.subplots(1, 1, figsize=(12, 7))

group = group.sort_index(ascending=False) # 역순 정렬
total=group['male']+group['female'] # 각 그룹별 합


ax.barh(group['male'].index, group['male']/total, 
        color='royalblue')

ax.barh(group['female'].index, group['female']/total, 
        left=group['male']/total, 
        color='tomato')

ax.set_xlim(0, 1)
for s in ['top', 'bottom', 'left', 'right']:
    ax.spines[s].set_visible(False)

plt.show()

set_xlim(0, 1)을 하지 않으면 오른쪽에 마진이 남기 때문에 설정해준다.

또, spines.set_visible(False)를 사용해서 테두리를 제거한다.

2-4. Overlapped Bar Plot

겹치는 투명도는 꼭 정해진 것이 아닌 다양한 실험을 통해 선택하면 됩니다.

group = group.sort_index() # 다시 정렬

fig, axes = plt.subplots(2, 2, figsize=(12, 12))
axes = axes.flatten()

for idx, alpha in enumerate([1, 0.7, 0.5, 0.3]):
    axes[idx].bar(group['male'].index, group['male'], 
                  color='royalblue', 
                  alpha=alpha)
    axes[idx].bar(group['female'].index, group['female'],
                  color='tomato',
                  alpha=alpha)
    axes[idx].set_title(f'Alpha = {alpha}')
    
for ax in axes:
    ax.set_ylim(0, 200)
    
    
plt.show()

좀 진한색은 0.5, 연한색은 0.7을 사용하는 것이 좋다

2-5. Grouped Bar Plot

크게 3가지 테크닉으로 구현 가능합니다.

  • x축 조정

  • width 조정

  • xticks, xticklabels

원래 x축이 0, 1, 2, 3로 시작한다면

- 한 그래프는 0-width/2, 1-width/2, 2-width/2 로 구성하면 되고
- 한 그래프는 0+width/2, 1+width/2, 2+width/2 로 구성하면 됩니다.

이 x좌표는 막대 그래프의 중심점을 의미한다

fig, ax = plt.subplots(1, 1, figsize=(12, 7))

idx = np.arange(len(group['male'].index))
width=0.35

ax.bar(idx-width/2, group['male'], 
       color='royalblue',
       width=width)

ax.bar(idx+width/2, group['female'], 
       color='tomato',
       width=width)

ax.set_xticks(idx)
ax.set_xticklabels(group['male'].index)
    
plt.show()

x축의 각 그래프 라벨을 정하려면 우선 set_xticks로 인덱스 넘버를 정해주고 이를 set_xticklabels를 이용해서 변경하는 절차를 거쳐야 한다.

그리고 추가적으로 label + legend를 달아 색에 대한 설명도 추가하면 좋습니다.

fig, ax = plt.subplots(1, 1, figsize=(12, 7))

idx = np.arange(len(group['male'].index))
width=0.35

ax.bar(idx-width/2, group['male'], 
       color='royalblue',
       width=width, label='Male')

ax.bar(idx+width/2, group['female'], 
       color='tomato',
       width=width, label='Female')

ax.set_xticks(idx)
ax.set_xticklabels(group['male'].index)
ax.legend()    
    
plt.show()

그렇다면 그룹이 N개 일때는 어떻게 하면 될까요?

그룹의 개수에 따라 x좌표는 다음과 같습니다.

  • 2개 : -1/2, +1/2

  • 3개 : -1, 0, +1 (-2/2, 0, +2/2)

  • 4개 : -3/2, -1/2, +1/2, +3/2

규칙이 보이시나요?

−N−12에서N−12−\frac{N−1}{2}에서 \frac{N−1}{2}−2N−1​에서2N−1​까지 분자에 2간격으로 커지는 것이 특징입니다.

그렇다면 index i(zero-index)에 대해서는 다음과 같이 x좌표를 계산할 수 있습니다.

x+−N+1+2×i2×width x+\frac{−N+1+2×i}{2}×widthx+2−N+1+2×i​×width

이번엔 인종/민족 그룹에 따른 Parental Level of Education Grouped Bar Plot으로 그려보겠습니다.

group = student.groupby('parental level of education')['race/ethnicity'].value_counts().sort_index()
group_list = sorted(student['race/ethnicity'].unique())
edu_lv = student['parental level of education'].unique()
fig, ax = plt.subplots(1, 1, figsize=(13, 7))

x = np.arange(len(group_list))
width=0.12

for idx, g in enumerate(edu_lv):
    ax.bar(x+(-len(edu_lv)+1+2*idx)*width/2, group[g], 
       width=width, label=g)

ax.set_xticks(x)
ax.set_xticklabels(group_list)
ax.legend()    
    
plt.show()

이 때 width는 전체가 1 이므로 개수가 n개이면 1/n 보다 작게해서 잘 나눠지면서 가독성도 좋게 할 수 있다. (1/n 으로 설정하면 꽉차보이기 때문) 그렇지만, matplotlib만을 이용할 때의 이야기이고 후에 다른 라이브러리를 배우게 되면 직접 width를 설정할 일은 없게된다.

3. 정확한 Bar Plot

3-1. Principle of Proportion Ink

성별에 따른 성적을 막대그래프로 비교해보겠습니다.

score = student.groupby('gender').mean().T
score

gender

female

male

math score

64.394515

70.479087

reading score

72.845992

67.178707

writing score

72.995781

65.041825

fig, axes = plt.subplots(1, 2, figsize=(15, 7))

idx = np.arange(len(score.index))
width=0.3

for ax in axes:
    ax.bar(idx-width/2, score['male'], 
           color='royalblue',
           width=width)

    ax.bar(idx+width/2, score['female'], 
           color='tomato',
           width=width)

    ax.set_xticks(idx)
    ax.set_xticklabels(score.index)

axes[0].set_ylim(60, 75)
    
plt.show()

정확한 정보량을 통한 비교를 원한다면 오른쪽이, 정보를 통한 강조(부각)가 중요하다면 왼쪽으로 시각화 할 수 있다.

비교를 위한다면 세로를 늘리는 게 더 좋을 수 있습니다.

fig, ax = plt.subplots(1, 1, figsize=(6, 10))

idx = np.arange(len(score.index))
width=0.3

ax.bar(idx-width/2, score['male'], 
       color='royalblue',
       width=width)

ax.bar(idx+width/2, score['female'], 
       color='tomato',
       width=width)

ax.set_xticks(idx)
ax.set_xticklabels(score.index)


    
plt.show()

3-2 데이터 정렬하기

student.head()

gender

race/ethnicity

parental level of education

lunch

test preparation course

math score

reading score

writing score

0

male

group D

high school

standard

none

95

92

86

1

female

group D

high school

standard

none

86

94

93

2

male

group A

some high school

standard

none

58

57

52

3

female

group E

associate's degree

standard

none

93

100

96

4

female

group C

high school

free/reduced

none

29

48

43

3-3. 적절한 공간 활용

다양한 공간 테크닉을 살펴보겠습니다.

대조군을 위해 2개의 같은 플롯을 그려보겠습니다.

  • X/Y axis Limit (.set_xlim(), .set_ylime())

  • Margins (.margins())

  • Gap (width)

  • Spines (.spines[spine].set_visible())

group_cnt = student['race/ethnicity'].value_counts().sort_index()

fig = plt.figure(figsize=(15, 7))

ax_basic = fig.add_subplot(1, 2, 1)
ax = fig.add_subplot(1, 2, 2)

ax_basic.bar(group_cnt.index, group_cnt)
ax.bar(group_cnt.index, group_cnt,
       width=0.7,
       edgecolor='black',
       linewidth=2,
       color='royalblue'
      )

ax.margins(0.1, 0.1)

for s in ['top', 'right']:
    ax.spines[s].set_visible(False)

plt.show()

3-4. 복잡함과 단순함

그리드나 텍스트를 추가해보며 어떤 게 더 좋을지 고민해보겠습니다.

group_cnt = student['race/ethnicity'].value_counts().sort_index()

fig, axes = plt.subplots(1, 2, figsize=(15, 7))

for ax in axes:
    ax.bar(group_cnt.index, group_cnt,
           width=0.7,
           edgecolor='black',
           linewidth=2,
           color='royalblue',
           zorder=10
          )

    ax.margins(0.1, 0.1)

    for s in ['top', 'right']:
        ax.spines[s].set_visible(False)

axes[1].grid(zorder=0)

for idx, value in zip(group_cnt.index, group_cnt):
    axes[1].text(idx, value+5, s=value,
                 ha='center', 
                 fontweight='bold'
                )
        
plt.show()

3-5. ETC

오차막대(errorbar)를 사용하여 편차 등의 정보를 추가해보겠습니다.

score_var = student.groupby('gender').std().T
score_var

gender

female

male

math score

15.357834

14.134272

reading score

14.532297

13.555754

writing score

15.000634

13.660167

fig, ax = plt.subplots(1, 1, figsize=(10, 10))

idx = np.arange(len(score.index))
width=0.3


ax.bar(idx-width/2, score['male'], 
       color='royalblue',
       width=width,
       label='Male',
       yerr=score_var['male'],
       capsize=10
      )

ax.bar(idx+width/2, score['female'], 
       color='tomato',
       width=width,
       label='Female',
       yerr=score_var['female'],
       capsize=10
      )

ax.set_xticks(idx)
ax.set_xticklabels(score.index)
ax.set_ylim(0, 100)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

ax.legend()
ax.set_title('Gender / Score', fontsize=20)
ax.set_xlabel('Subject', fontweight='bold')
ax.set_ylabel('Score', fontweight='bold')

plt.show()

데이터는 Student Score Dataset입니다.

link