[AITech] 20220211 - Polar Coordination&Radar Chart
학습 내용
이번 포스팅에서는 matplotlib을 이용해 극 좌표계를 다루는 방법에 대해 알아보겠습니다.
Polar Coordination
Polar Coordinate 만들기
서브플롯 ax
를 만들 때 projection='polar'
또는 polar=True
파라미터를 전달하면 다음과 같이 극좌표계를 사용할 수 있습니다.
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar') # polar=True
plt.show()
Polar Coordinate 조정하기
set_rmax
: 반지름 조정set_rmin
을 조정한다면? 도넛형태가 될 수 있을까??- 중앙에서 r=1로 시작할 뿐!!
set_thetamax()
: 각도의 max값set_thetamin()
: 각도의 min값set_rticks
: 반지름 표기 grid 조정set_rlabel_position
: 반지름 label이 적히는 위치의 각도 조정
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
ax.set_rmax(2)
ax.set_rmin(1)
ax.set_thetamin(45)
ax.set_thetamax(135)
ax.set_rticks([1, 1.2, 1.4, 1.6, 1.8, 2.0])
# ax.set_rlabel_position(90)
plt.show()
Polar 기본 차트
scatter()
: 기존 산점도와 같음 (theta, r 순서)
np.random.seed(19680801)
N = 100
r = 2 * np.random.rand(N)
theta = 2 * np.pi * np.random.rand(N)
area = 200 * r**2
colors = theta
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
c = ax.scatter(theta, r, c=colors, s=area, cmap='hsv', alpha=0.75)
plt.show()
bar()
- Polar coordinate에서의 bar plot은 실질적인 bar 간 크기 비교가 어려우므로 목적에 따라 잘 사용해야 함
np.random.seed(19680801)
N = 6
r = np.random.rand(N)
theta = np.linspace(0, 2*np.pi, N, endpoint=False)
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
ax.bar(theta, r, width=0.5, alpha=0.5)
plt.show()
plot()
np.random.seed(19680801)
N = 1000
r = np.linspace(0, 1, N)
theta = np.linspace(0, 2*np.pi, N)
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
ax.plot(theta, r)
plt.show()
fill()
np.random.seed(19680801)
N = 1000
r = np.linspace(0, 1, N)
theta = np.linspace(0, 2*np.pi, N)
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
ax.fill(theta, r)
plt.show()
Radar Chart
Radar Chart
는 극 좌표계를 사용하는 대표적인 차트로, 중심점을 기준으로 N개의 변수 값을 표현하며 데이터의 Quality를 표현하기에 좋습니다.
캐릭터 등의 능력치를 표현할 때 자주 사용하죠.
Radar chart의 주의점으로는 다음과 같은 것들이 있습니다.
- 각 feature는 독립적이며, 척도가 같아야 합니다.
- 다각형의 면적이 중요하지만, 이는 feature의 순서에 따라 많이 달라집니다.
- feature의 개수가 많을수록 가독성이 떨어집니다.
여기서는 아래와 같은 Pokemon with Stat 데이터셋을 사용하여 만들어보겠습니다.
pokemon = pd.read_csv('./pokemon.csv')
pokemon.head()
Radar Chart 기본 구성
# 나타낼 feature 선택
stats = ["HP", "Attack", "Defense", "Sp. Atk", "Sp. Def", "Speed"]
values = pokemon.iloc[0][stats].to_list() # [45, 49, 49, 65, 65, 45]
# 각은 2𝜋 를 6등분
theta = np.linspace(0, 2*np.pi, 6, endpoint=False) # [0. 1.04719755 2.0943951 3.14159265 4.1887902 5.23598776]
# 끝 점을 포함하기 위해 마지막 데이터를 포함
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
values.append(values[0]) # [45, 49, 49, 65, 65, 45, 45]
theta = theta.tolist() + [theta[0]] # [0.0, 1.0471975511965976, 2.0943951023931953, 3.141592653589793, 4.1887902047863905, 5.235987755982988, 0.0]
ax.plot(theta, values)
ax.fill(theta, values, alpha=0.5)
plt.show()
커스텀 및 조정
set_thetagrids
: 각도에 따른 그리드 및 ticklabels 변경set_theta_offset
: 시작 각도 변경
fig = plt.figure(figsize=(4, 4))
ax = fig.add_subplot(111, projection='polar')
values = pokemon.iloc[0][stats].to_list()
values.append(values[0])
theta = theta
ax.plot(theta, values)
ax.fill(theta, values, alpha=0.5)
ax.set_thetagrids([n*60 for n in range(6)], stats)
ax.set_theta_offset(np.pi/2)
ax.set_rmax(100)
plt.show()
fig = plt.figure(figsize=(14, 4))
for idx in range(3):
ax = fig.add_subplot(1,3,idx+1, projection='polar')
values = pokemon.iloc[idx][stats].to_list()
values.append(values[0])
ax.plot(theta, values, color='forestgreen')
ax.fill(theta, values, color='forestgreen', alpha=0.3)
ax.set_rmax(100)
ax.set_thetagrids([n*60 for n in range(6)], stats)
ax.set_theta_offset(np.pi/2)
plt.show()
Leave a comment