시각화를 진행하다보면 데이터로 그려진 그래프만으로는 부족한 경우가 있습니다. 아래와 같은 사례가 있을 수 있죠.
- 특정 값 (최대, 최소 등)에 대한 지칭이 필요하다.
- 어느 한점으로부터 얼마나 멀리 떨어져 있는지 시각적으로 바로 알아차리게 하고 싶다.
- 특정한 구간을 표시하고 싶다.
이번 글에서는 시각화 효과를 높이기 위해 다양한 도구들에 대해 살펴보려고 합니다.
다양한 그리드 생성하기
matplotlib에서는 pyplot.grid를 통해 그리드를 생성할 수 있습니다. 하지만, 그리드의 사전적 의미처럼 격자 형태의 비교적 단순한 형태의 그리드만 생성할 수 있어 유연성에 있어서는 조금 아쉽습니다. 대신에 matplotlib에서 제공하고 있는 다양한 차트 시각화 도구를 이용해 색상, 선의 유형, 두께 등을 조절해서 조금 덜 보이도록 해서 다양한 그리드를 생성할 수 있습니다. 여기선 직선과 원 형태의 그리드의 간단한 형태를 생성해보도록 하겠습니다.
먼저, 아래와 같이 [0,1] 사이에 10개의 랜덤 데이터를 생성하겠습니다. 이 데이터를 바탕으로 다양한 보조선을 그려보도록 하겠습니다.
import numpy as np
import matplotlib.pyplot as plt
x = np.random.uniform(0, 1, size=10)
y = np.random.uniform(0, 1, size=10)
np.random.seed(1)
# 실습 1. x + y = c 그리기
x + y = c (c는 바뀜)직선을 그리는 방법은 1차 함수의 x, y 절편을 변화시키면서 그 값을 변화시켜주면 됩니다. 주된 그래프가 아니기 때문에 잘 보이지 않게 점선(--), 회색, 투명도를 설정하고 그려줄 수 있습니다.
fig, ax = plt.subplots()
ax.scatter(x, y)
# Grid : x + y = c
x_start = np.linspace(0, 2.2, 12, endpoint=True) # 절편 값 변화에 따라 나눔
for xs in x_start:
ax.plot([xs, 0], [0, xs], linestyle='--', color='gray', alpha=0.5, linewidth=1)
ax.set_title(r"Grid ($x+y=c$)", fontsize=15,va= 'center', fontweight='semibold')
ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)
plt.show()
# 실습 2. y = cx 그리기
y = cx (c는 바뀜) 직선은 위와 다르게 기울기가 변화하는 직선입니다. 이를 그리는 방법은 기울기의 변화를 원하는 방식으로 변화를 주면서 직선을 그려주면 됩니다. 메인 그래프가 아니라 그리드이기 때문에 잘 보이지 않게 점선(--), 회색, 투명도를 설정하고 그려줄 수 있습니다.
fig, ax= plt.subplots()
ax.scatter(x, y)
# Grid : y = cx
radian = np.linspace(0, np.pi/2, 11, endpoint=True) # (여기선 동일하게) 각도를 나눔
for rad in radian:
ax.plot([0,2], [0, 2*np.tan(rad)], linestyle='--', color='gray', alpha=0.5, linewidth=1)
ax.set_title(r"Grid ($y=cx$)", fontsize=15,va= 'center', fontweight='semibold')
ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)
plt.show()
# 실습 3. (a, b)가 중심인 원 그리기
특정 점에서 얼마나 떨어져 있는지 살펴보기 위해선 원형 그리드가 효과적입니다. 실제로 (유클리드 공간에서) 원의 정의가 같은 거리에 있는 점들의 집합이기 때문에 정확한 활용이죠. 여기선 x[2], y[2] 값을 중심으로 얼마나 떨어져 있는지 살펴보는 코드는 아래와 같습니다. (그림을 보면 조금 이상하긴 하지만... 조금씩만 조정해주면 될 것 같습니다)
fig, ax= plt.subplots()
ax.scatter(x, y)
## Grid : (x-a)**2 + (y-b)**2 = r**2
a = x[2]
b = y[2]
rs = np.linspace(0.1, 0.8, 8, endpoint=True)
for r in rs:
xx = r*np.cos(np.linspace(0, 2*np.pi, 100))
yy = r*np.sin(np.linspace(0, 2*np.pi, 100))
ax.plot(xx+a, yy+b, linestyle='--', color='gray', alpha=0.5, linewidth=1)
ax.text(a+r*np.cos(np.pi/4), b-r*np.sin(np.pi/4), f'{r:.1}', color='gray')
ax.set_title(r"Grid ($(x-a)^2+(y-b)^2=c$)", fontsize=15,va= 'center', fontweight='semibold')
ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)
plt.show()
보조 선/면 그리기
시각화는 데이터를 보기 좋게 만드는 것입니다. 앞서 그리드 외에도 데이터를 살펴보기 좋게끔 만들기 위해 보조 선/면을 그리는 방법이 있습니다. 아래 그림은 kaggle에서 볼 수 있는 시각화 사례입니다.
pyplot에서 보조선(axhline, axvline)과 보조면(axhspan, axvspan)을 그릴 수 있는 다양한 메서드를 제공하고 있습니다.
# 실습 4. 보조 선 그리기
보조 선을 그리는 방법은 앞에서 설명한 메서드(axvline, axhline)을 사용하거나 pyplot.plot 을 사용하는 방법이 있습니다. 정답은 없고, 둘 중 편한 것을 사용하면 될 것 같습니다. 아래 코드는 두가지 모두 사용한 방법을 기재했습니다. 조금 주의할 것은 axvline, axhline에서 xmin과 xmax는 0~1 사이의 상대적인 위치를 넣어야 하기 때문에 표화가 필요합니다.
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
x = np.arange(20)
y = np.random.rand(20)
ax = fig.add_subplot(111)
ax.plot(x, y,
color='lightgray',
linewidth=2,)
ax.set_xlim(-1, 21)
# max
# ax.plot([-1, x[np.argmax(y)]], [np.max(y)]*2,
# linestyle='--', color='tomato')
ax.axhline(y=np.max(y), xmin=0, xmax= x[np.argmax(y)] / len(x),
linestyle='--', color='tomato')
ax.scatter(x[np.argmax(y)], np.max(y),
c='tomato',s=50, zorder=20)
# min
# ax.plot([-1, x[np.argmin(y)]], [np.min(y)]*2,
# linestyle='--', color='royalblue')
ax.axhline(y=np.min(y), xmin=0, xmax= x[np.argmin(y)] / len(x),
linestyle='--', color='royalblue')
ax.scatter(x[np.argmin(y)], np.min(y),
c='royalblue',s=50, zorder=20)
plt.show()
# 실습 5. 보조 면 그리기
보조 면의 사용은 axvspan, axhspan을 통해 사용이 가능합니다. 사용방법은 위에 보조선과 거의 유사합니다.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set_aspect(1)
ax.axvspan(0,0.5, ymin=0.3, ymax=0.7, color='red')
ax.axhspan(0.3,0.7, xmin=0.3, xmax=0.7, color='blue')
plt.show()
ax.set_xlim(-0.1, 1)
ax.set_ylim(-0.1, 1)
plt.show()
참고자료
[1] 🎬 Storytelling with Data - Netflix ver. (kaggle.com)
'Python > Visualization' 카테고리의 다른 글
Matplotlib으로 극좌표계 시각화하기 (polar plot) | 게임 능력치 시각화 (1) | 2024.08.26 |
---|---|
Matplotlib을 이용한 막대 그래프 만들기 (bar plot) | 누적 막대 그래프, 비율, 묶은 막대 그래프 (0) | 2024.08.24 |
Matplotlib으로 산점도 그리기 (Scatter plot) (0) | 2024.08.23 |
Matplotlib으로 선 그래프(line plot) 그리기 | 보조축, 그래프 여러개 그리는 방법 (0) | 2024.08.23 |
Basemap 위에 국내 발전사업허가 현황 버블차트 그리기 | Matplotlib (0) | 2021.12.20 |