본문 바로가기
데이터 분석/시각화

Matplotlib 서로 다른 y축 적용하기

by 부자 꽁냥이 2021. 7. 13.

시각화를 하다 보면 같은 x축에 대하여 서로 다른 y축을 적용해야 할  때가 있습니다. 이때 y축의 단위가 같다면 상관이 없지만 다르다면 주의해야 합니다. 

 

아래 그림은 코사인 함수와 직선 함수를 각각 그린 것입니다. 보시면 알겠지만 x축의 범위는 같고 y축의 범위가 다른 것을 알 수 있어요~

 

 

이제 위 두 그래프를 그냥 합친다면 어떻게 될까요? 

 

 

코사인 함수의 범위는 -1 부터 1까지인데 직선 그래프의 y값 범위가 0부터 1000으로 차이가 많이 나기 때문에 코사인 함수의 특성이 제대로 보이지 않게 됩니다. 이때에는 y축을 2개를 사용하여 그래프의 형태가 제대로 나타나게 해줘야 합니다. Matplotlib에서는 이처럼 x축은 공유하지만 범위가 서로 다른 여러 y축이 있을 경우 이를 다중 축으로 나타낼 수 있습니다. 이번 포스팅에서는 Matplotlib을 이용하여 2중 또는 다중 y축을 표시하는 방법에 대해서 알아보겠습니다.

 

여기서 다루는 내용은 다음과 같습니다.

 

1. 서로 다른 y축 좌/우에 표시하기

2. 한쪽에 서로 다른 y축 표시하기


   1. 서로 다른 y축 좌/우에 표시하기

1. y축이 2개인 경우

여기서는 2개의 y값에 대해서 축을 좌 우에 표시하는 방법을 알아보겠습니다. 먼저 여기에서 사용할 데이터를 만들어 줍니다.

 

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0,10, 0.1)
y1 = np.cos(x)
y2 = 100*x+np.random.normal(len(x))

 

Matplotlib은 twinx 클래스를 이용하여 x축을 공유하는 y축을 여러개 만들어 줄 수 있습니다. 사용법은 아래 코드를 살펴보면서 감을 익히시면 될듯합니다.

 

fig = plt.figure(figsize=(6,6)) ## 캔버스 생성
fig.set_facecolor('white')
ax1 = fig.add_subplot() ## axes 생성

color1 = 'b'
ax1.plot(x, y2, color=color1)
ax1.set_xlabel('x')
ax1.set_ylabel('Line', color=color1)
ax1.tick_params(axis='y', labelcolor=color1)

color2 = 'r'
ax2 = ax1.twinx()
ax2.plot(x, y1, color=color2)
ax2.set_ylabel('Cos', color=color2)
ax2.tick_params(axis='y', labelcolor=color2)

plt.show()

 

line 5~9

먼저 기존 x/y축에다가 y2에 해당하는 값을 그려줍니다(line 6). 색상, y라벨, y축 눈금은 모두 파란색으로 지정하였습니다(line 7~9).

 

line 12

twinx를 이용하여 새로운 x/y축 ax2을 생성합니다. 이때 x축은 기존 x/y 축인 ax1과 공유됩니다. 그리고 ax2의 y축은 기본적으로 오른쪽에 배치됩니다.

 

line 13~15

코사인 그래프를 그립니다. 그래프 색상, y라벨, y축 눈금은 빨간색으로 지정했습니다.

 

코드를 실행하면 아래와 같이 서로 다른 y축이 생겨서 그래프의 형태를 정확히 볼 수 있습니다.

2. y축이 3개 이상인 경우

만약 y값이 3개 이상인 경우에는 어떻게 그려야할까요? twinx 클래스 인스턴스를 하나 더 만들고 한쪽에는 y축 1개 다른 쪽에는 2개의 축을 표시하면 됩니다. 이제 그 방법을 알아볼까요? 먼저 sin값을 나타내는 y3를 하나 더 만들어 줍니다.

 

x = np.arange(0,10, 0.1)
y1 = np.cos(x)
y2 = 100*x+np.random.normal(len(x))
y3 = 0.01*np.sin(x)

 

꽁냥이는 왼쪽에는 1개, 오른쪽에는 2개 y축을 표시할 거예요. y1, y2는 앞에서 살펴본 것과 동일하고 y3를 표시할 축을 하나 더 만들기 위해 twinx 클래스를 만들어준 뒤(line 18) y축을 표시할 때 좀 더 오른쪽으로 표시하기 위해 spines.right.set_position 메서드를 이용합니다. 이 메서드는 튜플을 인자로 받는데 첫 번째 원소에는 'axes' 문자열, 두 번째 원소에는 오른쪽으로 얼마나 이동시킬 것인지를 결정하는 숫자를 넣어줍니다(line 22).

 

fig = plt.figure(figsize=(6,6)) ## 캔버스 생성
fig.set_facecolor('white')
ax1 = fig.add_subplot() ## axes 생성

color1 = 'b'
ax1.plot(x, y2, color=color1)
ax1.set_xlabel('x')
ax1.set_ylabel('Line', color=color1)
ax1.tick_params(axis='y', labelcolor=color1)

color2 = 'r'
ax2 = ax1.twinx()
ax2.plot(x, y1, color=color2)
ax2.set_ylabel('Cos', color=color2)
ax2.tick_params(axis='y', labelcolor=color2)

color3 = 'g'
ax3 = ax1.twinx()
ax3.plot(x, y3, color=color3)
ax3.set_ylabel('Sin', color=color3)
ax3.tick_params(axis='y', labelcolor=color3)
ax3.spines.right.set_position(("axes", 1.2)) ## 오른쪽 옆에 y축 추가

plt.show()

 

코드를 실행하면 아래와 같이 왼쪽에 1, 오른쪽에 2개의 y축이 표시되어 그래프의 형태를 정확하게 표현할 수 있습니다.

 

 

만약 왼쪽에 2개의 y축을 표시하고 싶다면 아래와 같이 y축이 좀 더 왼쪽으로 표시되도록 설정하고(line 22) y라벨과 y축 눈금을 모두 왼쪽으로 보내줍니다(line 23~24).

 

fig = plt.figure(figsize=(6,6)) ## 캔버스 생성
fig.set_facecolor('white')
ax1 = fig.add_subplot() ## axes 생성

color1 = 'b'
ax1.plot(x, y2, color=color1)
ax1.set_xlabel('x')
ax1.set_ylabel('Line', color=color1)
ax1.tick_params(axis='y', labelcolor=color1)

color2 = 'r'
ax2 = ax1.twinx()
ax2.plot(x, y1, color=color2)
ax2.set_ylabel('Cos', color=color2)
ax2.tick_params(axis='y', labelcolor=color2)

color3 = 'g'
ax3 = ax1.twinx()
ax3.plot(x, y3, color=color3)
ax3.set_ylabel('Sin', color=color3)
ax3.tick_params(axis='y', labelcolor=color3)
ax3.spines.left.set_position(("axes", -0.2)) ## 왼쪽 옆에 y축 추가
ax3.yaxis.set_label_position('left') ## y라벨 왼쪽에 표시
ax3.yaxis.set_ticks_position('left') ## Y축 눈금 왼쪽에 표시

plt.show()


   2. 한쪽에 서로 다른 y축 표시하기

1. 오른쪽에 여러 y축 표시하기

이번에는 좌우가 아닌 한쪽에 여러 y축을 표시하는 방법에 대해서 알아보았습니다. 사실 새로운 것은 없고 앞에서 배운 것을 응용하면 됩니다. 먼저 오른쪽에 y축 3개를 표시하도록 하겠습니다. 여기서는 기존 왼쪽에 표시되었던 y축을 감춘 뒤(line 6) twinx를 3번 호출하여 오른쪽에 적절하게 배치시켜줍니다. 앞에서 다룬 내용이므로 추가적인 설명은 생략합니다.

 

fig = plt.figure(figsize=(6,6)) ## 캔버스 생성
fig.set_facecolor('white')
ax1 = fig.add_subplot() ## axes 생성

color1 = 'b'
ax1.yaxis.set_visible(False) ## 기존 왼쪽 y축 숨김

ax2 = ax1.twinx()
ax2.plot(x, y2, color=color1)
ax2.set_xlabel('x')
ax2.set_ylabel('Line', color=color1)
ax2.tick_params(axis='y', labelcolor=color1)

color2 = 'r'
ax3 = ax1.twinx()
ax3.plot(x, y1, color=color2)
ax3.set_ylabel('Cos', color=color2)
ax3.tick_params(axis='y', labelcolor=color2)
ax3.spines.right.set_position(("axes", 1.2)) ## 오른쪽 옆에 y축 추가

color3 = 'g'
ax4 = ax1.twinx()
ax4.plot(x, y3, color=color3)
ax4.set_ylabel('Sin', color=color3)
ax4.tick_params(axis='y', labelcolor=color3)
ax4.spines.right.set_position(("axes", 1.4)) ## 오른쪽 옆에 y축 추가

plt.show()

 

2. 왼쪽에 여러 y축 표시하기

이번엔 왼쪽에 여러 y축을 표시해보겠습니다. 여기서는 기존 왼쪽 y축을 숨길 필요가 없습니다.

 

fig = plt.figure(figsize=(6,6)) ## 캔버스 생성
fig.set_facecolor('white')
ax1 = fig.add_subplot() ## axes 생성

color1 = 'b'
ax1.plot(x, y2, color=color1)
ax1.set_xlabel('x')
ax1.set_ylabel('Line', color=color1)
ax1.tick_params(axis='y', labelcolor=color1)

color2 = 'r'
ax2 = ax1.twinx()
ax2.plot(x, y1, color=color2)
ax2.set_ylabel('Cos', color=color2)
ax2.tick_params(axis='y', labelcolor=color2)
ax2.spines.left.set_position(("axes", -0.2)) ## 왼쪽 옆에 y축 추가
ax2.yaxis.set_label_position('left') ## y라벨 왼쪽에 표시
ax2.yaxis.set_ticks_position('left') ## Y축 눈금 왼쪽에 표시

color3 = 'g'
ax3 = ax1.twinx()
ax3.plot(x, y3, color=color3)
ax3.set_ylabel('Sin', color=color3)
ax3.tick_params(axis='y', labelcolor=color3)
ax3.spines.left.set_position(("axes", -0.4)) ## 왼쪽 옆에 y축 추가
ax3.yaxis.set_label_position('left') ## y라벨 왼쪽에 표시
ax3.yaxis.set_ticks_position('left') ## Y축 눈금 왼쪽에 표시

plt.show()

 

 


이번 포스팅에서는 서로 다른 범위를 갖는 데이터를 여러 y축을 사용하여 하나의 그래프에 나타내는 방법을 알아보았습니다. 오늘 알아본 내용은 꽤 많이 사용되므로 알아두시면 반드시 도움이 될 거예요. 그럼 다음에도 좋은 내용으로 찾아뵙겠습니다. 안녕히 계세요~

 

참고자료

https://matplotlib.org/2.2.5/gallery/api/two_scales.html

https://stackoverflow.com/questions/9103166/multiple-axis-in-matplotlib-with-different-scales

https://matplotlib.org/stable/gallery/ticks_and_spines/multiple_yaxis_with_spines.html

https://stackoverflow.com/questions/50381672/using-a-loop-to-define-multiple-y-axes-in-plotly

https://stackoverflow.com/questions/20146652/two-y-axis-on-the-left-side-of-the-figure


댓글


맨 위로