본문 바로가기
Python/matplotlib

[matplotlib] x축과 y축을 그리기: spines

by ds31x 2023. 8. 8.

schematic graphs 에서는 아래 그림처럼 $y$, $x$가 각각 0인 x-axis, y-axis가 그려지고 그 위에 graph가 그려지는 경우가 많다 (사람 손으로 그릴 경우 대부분이 이 경우이다.)

sinc 함수에 대한 schematic graph

matplotlib에서도 여러 방법으로 특정 좌표(보통은 0)에 x-axis와 y-axis를 그려줄 수 있다.


axhline과 axvline 사용하기

가장 간단한 방법은 Axes 객체의 axhlineaxvline을 이용하는 것이다.

축에 대해 horizontal line과 vertical line을 그려주는 이들 메소드를 이용하면 특정 좌표에 쉽게 x-axis와 y-axis를 그려줄 수 있다.

다음 snippet은 x좌표가 0인 곳에 y축을, y좌표가 0인 곳에 x축을 black 의 색으로 그려준다.

fig, ax = plt.subplots(figsize=(10,5))
ax.axhline(0, color = 'k')
ax.axvline(0, color = 'k')
ax.plot(x,y)

 

x,y의 값을 다음과 같이 설정했다고 하자.

x = np.linspace(-2 * np.pi, 2 * np.pi, 170, endpoint=True)
y = np.sin(x**3 / 2

 

결과는 다음과 같음.

이 방법의 단점은 xtick, ytick 정보는 여전히 left spine과 bottom spine에서 그려진다는 점이다.

 

xticks과 yticks을 설정하기가 까다롭기 때문에 이 방법은 간단히 (그리고 빨리) 도식적으로 그리는 경우에 주로 이용된다.


Spine사용하기

matplotlib에서
spine은 graph 영역을 표시하고 있는 박스 모양을 이루는 4개의 선분을 가르킨다.
Axes 객체에서 spines property를 통해 접근 가능함.

 

 

다른 방법은 이미 xtick, ytick이 설정가능하도록 되어 있는 spines['left']spines['bottom']을 이용하는 것이다.

  • 이 방법을 사용할 경우, graph 영역을 표시하는 박스는 사라지게 된다 (박스를 axhlineaxvline으로 그려줄 수도 있긴 함).
  • spine들은 'left', 'right', 'top', 'bottom'의 key를 통해 Axes의 객체 axspines attributes를 통해 접근할 수 있다.

처리과정은 다음과 같다.

  1. ax.spines['top']ax.spines['right']의 color를 none으로 지정하여 보이지않게 처리하고,
  2. ax.spines['bottom']을 x축으로 삼아 표시하고자 하는 y좌표로 이동시키고, ax.spines['left']도 표시하고자 하는 x좌표로 이동시키면 된다.

이동은 set_position 메서드를 사용하고 ('data', 원하는좌표값) 의 tuple객체를 argument로 넘겨주면 된다.

다음의 snippet을 참고하라.

ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0)

spine은 손쉽게 xticks와 yticks를 처리할 수 있다.

앞의 경우와 같은 x,y 데이터를 사용하고 다음과 같이 xticks와 yticks를 처리했다고 하자.

ax.set_xticks([-10,-5,5,10])
ax.set_yticks([0.5,1.]

그러면 결과는 다음과 같음.

xticks들이 일부 잘 안보이는 경우가 발생하는데
이 경우, ax.set_axisbelow(False)를 호출하고 각
ticke들의 bbox 의 face color등을 흰색으로 처리하면 된다.


다음 snippet을 참고하라.

ax.set_axisbelow(False)
# print(line.zorder)

for label in ax.get_xticklabels() + ax.get_yticklabels():
  # line 위에 label이 잘보이도록 처리하기 위해서 

  # label의 bbox의 zorder도 label수준이 3으로 설정해도 동작하지 않음. 
  # ax.set_axisbelow(False) 처리를 해줘야 함.
  # label.set_bbox(dict(facecolor='white', edgecolor='white', zorder=3))
  # print(label.zorder)
  label.set_bbox(dict(facecolor='white', edgecolor='white')

 

결과는 다음과 같음.

728x90

'Python > matplotlib' 카테고리의 다른 글

[matplotlib] Layout Managers: GridSpec and subplot2grid  (1) 2024.01.22
[matplotlib] 3D Plot  (0) 2024.01.21
[matplotlib] line 및 marker 설정하기.  (0) 2023.07.21
[matplotlib] : backend 란  (0) 2023.07.20
[matplotlib]: Figure and Axes  (0) 2023.07.20