소개
산점도(scatter plot)는 두 변수 사이에 어떤 관계가 있는지 확인하고자 할 때 2차원 데이터를 시각화하는 데 매우 유용한 도구입니다. 산점도는 데이터를 X값과 Y값을 가진 점(dot) 형태로 표현하는 차트입니다.
구현 방법
1. 다음 명령어로 matplotlib을 설치합니다.
pip install matplotlib
2. matplotlib을 임포트합니다.
import matplotlib.pyplot as plt
tennis_stats = (('Federer', 20),('Nadal', 20),('Djokovic', 17),('Sampras', 14),('Emerson', 12),('laver', 11),('Murray', 3),('Wawrinka', 3),('Zverev', 0),('Theim', 1),('Medvedev',0),('Tsitsipas', 0),('Dimitrov', 0),('Rublev', 0))
3. 다음 단계는 데이터를 배열 형식으로 준비하는 것입니다. 데이터베이스나 스프레드시트에서 데이터를 읽어와 아래와 같은 형식으로 가공할 수도 있습니다.
titles = [title for player, title in tennis_stats]
players = [player for player, title in tennis_stats]
4. matplotlib의 다른 메서드와 마찬가지로 .scatter 메서드의 매개변수는 X값과 Y값의 배열을 필요로 합니다.
참고 - X값과 Y값은 반드시 같은 크기여야 하며, 데이터는 기본적으로 float형으로 변환됩니다.
plt.scatter(titles, players)
<matplotlib.collections.PathCollection at 0x28df3684ac0>

5. x축에 표시된 그랜드슬램 타이틀 수가 소수(float)로 나타나는 것을 볼 수 있습니다. 이 값을 정수로 변환하고, 아래 함수에서 x축과 y축에 라벨을 추가해 보겠습니다. 축 포맷터는 .set_major_formatter로 덮어쓸 수 있습니다.
from matplotlib.ticker import FuncFormatter
def format_titles(title, pos):
return '{}'.format(int(title))
plt.gca().xaxis.set_major_formatter(FuncFormatter(format_titles))
plt.xlabel('Grandslam Titles')
plt.ylabel('Tennis Player')
plt.scatter(titles, players)

6. 산점도를 단순한 2D 차트라고 생각하지 마세요. 산점도에는 세 번째 차원(면적·크기)뿐만 아니라 네 번째 차원(색상)까지 추가할 수 있습니다. 아래에서 어떤 작업을 수행할지 간단히 설명하겠습니다.
먼저 원하는 색상을 직접 정의한 다음, 반복문을 통해 색상을 무작위로 선택하여 각 데이터 값에 할당합니다.
alpha 값은 각 점을 반투명하게 만들어 점들이 겹치는 부분까지 확인할 수 있게 해줍니다. 이 값이 높을수록 점의 투명도는 낮아집니다.
import random
# 사용자 지정 색상 팔레트 정의
random_colors = ['#FF0000', '#FFFF00', '#FFFFF0', '#FFFFFF', '#00000F']
# 데이터 값 개수와 동일한 개수의 색상 설정
color = [random.choice(random_colors) for _ in range(len(titles))]
plt.scatter(titles, players, c=color, alpha=0.5)
<matplotlib.collections.PathCollection at 0x28df2242d00>

7. 이제 표현되는 점의 크기(면적)를 좀 더 크게 만들어 보겠습니다.
import random
# 사용자 지정 색상 팔레트 정의
random_colors = ['#FF0000', '#FFFF00', '#FFFFF0', '#FFFFFF', '#00000F']
# 데이터 값 개수와 동일한 개수의 색상 설정
color = [random.choice(random_colors) for _ in range(len(titles))]
# 크기 설정
size = [(50 * random.random()) ** 2 for _ in range(len(titles))]
plt.gca().xaxis.set_major_formatter(FuncFormatter(format_titles))
plt.xlabel('Grandslam Titles')
plt.ylabel('Tennis Player')
plt.scatter(titles, players, c=color, s=size, alpha=0.1)
<matplotlib.collections.PathCollection at 0x28df22e2430>

기억할 점은, 그래프의 궁극적인 목표는 데이터를 쉽게 이해할 수 있도록 만드는 것이라는 사실입니다.
여기서는 산점도로 할 수 있는 기본적인 활용 방법을 소개했습니다. 예를 들어 색상을 크기에 연동시켜 같은 크기의 점들은 동일한 색으로 표시하면 데이터를 구별하는 데 도움이 되는 등, 그 외에도 더 다양하게 활용할 수 있습니다.
더 자세한 내용 살펴보기 - https://matplotlib.org/
마지막으로 지금까지의 모든 내용을 하나로 합쳐 보겠습니다.
전체 예제
# 임포트
import matplotlib.pyplot as plt
import random
# 데이터 준비
tennis_stats = (('Federer', 20),('Nadal', 20),('Djokovic', 17),('Sampras', 14),('Emerson', 12),('laver', 11),('Murray', 3),('Wawrinka', 3),('Zverev', 0),('Theim', 1),('Medvedev',0),('Tsitsipas', 0),('Dimitrov', 0),('Rublev', 0))
titles = [title for player, title in tennis_stats]
players = [player for player, title in tennis_stats]
# 사용자 정의 함수
from matplotlib.ticker import FuncFormatter
def format_titles(title, pos):
return '{}'.format(int(title))
# 사용자 지정 색상 팔레트 정의
random_colors = ['#FF0000', '#FFFF00', '#FFFFF0', '#FFFFFF', '#00000F']
# 데이터 값 개수와 동일한 개수의 색상 설정
color = [random.choice(random_colors) for _ in range(len(titles))]
# 크기 설정
size = [(50 * random.random()) ** 2 for _ in range(len(titles))]
plt.gca().xaxis.set_major_formatter(FuncFormatter(format_titles))
plt.xlabel('Grandslam Titles')
plt.ylabel('Tennis Player')
plt.scatter(titles, players, c=color, s=size, alpha=0.1)
<matplotlib.collections.PathCollection at 0x2aa7676b670>
