이 포스팅은 시각화 정리 시리즈 16 편 중 2 번째 글 입니다.

  • Part 1 - 01: 라이브러리
  • Part 2 - This Post
  • Part 3 - 03: 산점도
  • Part 4 - 04: Circling을 통한 버블 플롯
  • Part 5 - 05: 선형 회귀 선을 포함한 산점도
  • Part 6 - 06: Strip plot
  • Part 7 - 07: Counts plot
  • Part 8 - 08: Marginal Histogram
  • Part 9 - 09: Correlation plot
  • Part 10 - 09: Marginal Boxplot
  • Part 11 - 10: Pair plot
  • Part 12 - 11: Diverging Bars
  • Part 13 - 12: Diverging lines with text
  • Part 14 - 13: Diverging Lollipop Chart with Markers
  • Part 15 - 14: Area chart
  • Part 16 - 15: Ordered Bar Chart
▼ 목록 보기

matplotlib의 기본적인 기능을 알아본다.

Figure, axes, subplots

기본 플롯은 Figure와 axes로 시작한다.

figure, axes

사실 그리는 방법은 여러가지가 있으나, 한가지 방법을 고수하는 것이 좋다. 이 글 에서는 OOP접근 방법에 기반하여 설명하도록 한다.

Basic Way

# figure 객체 생성
fig = plt.figure()

# subplot을 등록해준다. 1개만 그릴 경우 필요없지만,
# 명백하게 적어주는 습관을 들이는 것이 좋다.
ax1 = fig.add_subplot(1, 1, 1)

# some data
x = [1, 2, 3, 4, 5]
y = [3, 2, 1, 4, 5]

# plot basic things
ax1.plot(x, y);

아래의 방법도 위와 같은 결과를 가져온다.

# the same plot can be achieved doing this way
fig = plt.figure()
ax1 = fig.subplots()
ax1.plot(x, y);
# you can even simplify it more by just doing this
plt.plot(x, y);

간단하게 수행할 수 있지만, 명백한 방법을 일관되게 사용하는 것이 더 좋다. 이 방법 외에도 같은 결과를 만들 수 있는 다양한 코드가 존재한다. 이 부분에 대한 의문이 들었다면, matplotlib의 구조에 대해서 이해할 필요가 있다.

matplotlib의 구조

  1. Backend Layer
    • 가장 낮은 단계
    • %matplotlib inline 을 사용하면, plt.show()를 호출 할 필요없이 모든 것을 렌더링하도록 백엔드에 지시한다.
  2. Artist Layer
    • 이 레이어는 스파인, 축, 색상 등을 변경할 수 있는 가능성을 제공한다.
    • ax1.plot()을 호출 할 때 이 계층에 액세스한다. 앞으로 이 단계에서 많은 기능을 수행할 것이다.
  3. Script Layer
    • 빠른 플롯에 매우 편리하다.
    • plt.plot()과 같이 사용할 때 사용합니다. 여전히 강력하지만 2 레이어만큼 강력하지 않다.

Script Layer에서 call 했을 떄 실제 동작

script Layer actual calling Code Details
plt.subplot() fig = plt.figure() fig.add_subplot() figure를 생성하고 1개의 subplot을 fig에 추가한다.
plt.subplots() fig = plt.figure() fig.subplots(n, m) fig.subplots(n,m) 의 반환값은 (n,m)크기의 axes객체가 들어간 튜플이다. 따라서 plt.subplots()를 수행하면 fig와 axes 튜플 객체가 반환된다. fig, ax1 = plt.subplots() 이런식으로 받아주어야 한다.

Multiple plots

fig.subplots() 사용

fig = plt.figure()
# create a 4 plots and use tuple unpacking to name everyplot
# subplots() 라는 함수로 한번에 axes를 설정할 수 있다.
(ax1, ax2), (ax3, ax4) = fig.subplots(2,2)
ax1.plot([1,2,3], color = "red")
ax2.plot([3,2,1], color = "blue")
ax3.plot([4,4,4], color = "orange")
ax4.plot([5,4,5], color = "black")
plt.tight_layout()

plt.subplots() 사용

# you can do the same using a for loop
nrows = 2
ncolumns = 2
fig, axes = plt.subplots(nrows, ncolumns)    # return값이 2개이다.

# axes is just a tuple as we saw before
# since se specified
for row in range(nrows):
    for column in range(ncolumns):
        ax = axes[row, column]
        ax.plot(np.arange(10))

axis 안에 plot하기

fig = plt.figure(figsize = (20, 10))
# create a 4 plots and use tuple unpacking to name everyplot
(ax1, ax2), (ax3, ax4) = fig.subplots(2,2)
ax1.plot([1,2,3], color = "red")

ax2.plot([3,2,1], color = "blue")

ax3.plot([4,4,4], color = "orange")
ax3_bis = fig.add_axes([0.15, 0.15, 0.15, 0.15])
ax3_bis.plot([1,2,1], color = "pink") # you add it to the figure!
ax3_bis.annotate("Small annotation inside a small added axes",
                xy = (0.5, 0.5),
                xycoords = "axes fraction",
                va = "center",
                ha = "center")

ax4.plot([5,4,5], color = "black")
ax4.annotate("Just to demonstrate the power of matplotlib",
             xy = (0.5, 0.5), # fraction of the ax4. In the center.
             xycoords = "axes fraction", # you can also specify data and pass the values of the x and y axis.
             va = "center",
             ha = "center")

plt.tight_layout()

grid를 사용하여 예쁜 plot하기

gs를 사용하면, 행렬 처럼 슬라이싱을 하여 내가 원하는 곳에 그래프를 넣을 수 있다.

fig = plt.figure(figsize = (10, 5))
gs = fig.add_gridspec(3, 3)

ax1 = fig.add_subplot(gs[0, :])
ax1.plot([1,2,1,2])
ax1.set_title("Random text")

ax2 = fig.add_subplot(gs[1,0])
ax2.plot(1,3,1)

ax3 = fig.add_subplot(gs[1,1])
ax3.plot(3,1,3)

ax4 = fig.add_subplot(gs[2,:-1])
ax4.scatter([1,2,3], [1,2,3])

ax5 = fig.add_subplot(gs[1:, -1])
ax5.bar([1,2,3], [1,2,3])
ax5_bis = fig.add_axes([0.75, 0.5, 0.1, 0.1])
ax5_bis.plot([3,1,2])
plt.tight_layout()

reference

Plotting with Python: learn 80 plots STEP by STEP