matplotlib tutorial [Python] by 바죠

matplotlib tutorial

파이썬을 사용하는 중대한 이유중의 하나는 바로 그림 그리기이다. 단순히 그림 그리기를 넘어서 숨어있는 것이 있다.
그것은 바로 라이선스 구입 비용이다. 라이선스 구입 비용은 결단코 만만하지 않다. 크지도 않은 규모 직장을 생각해 보자. 적당한 규모의 단체라고 가정해도 쉽게 1억 정도는 각오해야만한다. 그것도 매년 지불해야만 하는 것이다. 이것은 명백한 고통이다. 어쩌면 파이썬을 배우기 전까지는 계속되는 고통일지도 모른다.

따라서, 현실적으로 모든 연구기관에서, 장기적으로 matplotlib 모듈을 이용한 그림 그리기는 매우 중요한 기술이 되어 버렸다.
파이썬 컴퓨터 언어를 배우는 것은 평생 발목을 잡을 수 있는 하나의 문제를 슬기롭게 해결하는 효과로 이어진다.

라이선스 문제를 넘어서도 마찬가지이다.
컴퓨터 시뮬레이션을 완료할 경우, 많은 경우, 그림으로 데이터를 설명해야만 하는 경우가 많다.
이 때, 파이썬은 그 능력을 발휘하고도 남는다. 얻어진 데이터를 추출하고, 원하는 식으로 편집하고 그림을 그릴 수 있게 해준다.

파이썬 언어의 강점은 매우 다양한 프로그램의 인풋자체를 프로그램 형식으로 넣을 수 있게 한다.
통상의 언어에서는 매우 간단한 인풋만 처리하여 문제가 되지 않는다.
하지만, 인터프리터 형식을 취하고 있는 파이썬 언어의 경우, 실제 계산과 별도로 프로그램의 인풋을 프로그램 형식으로 넣어줄 수 있다. 물론, 프로그램 언어를 알지 못할 경우는 무용지물이다.



matplotlib를 활용한 예제들을 보자.

단순한 파이썬의 자료형 list를 이용한 그림 그리기
numpy를 이용한 그림 그리기
미리 준비된 파일로부터 데이터를 직접 읽어서 그림 그리기
linear vs log
log vs linear
log vs log
2x1, 2x2 판넬 그림 그리기
웹페이지 자료를 읽어서 그림 그리기  http://incredible.egloos.com/7415000
3차원 그림 그리기
애니메이션 [데이터 업데이트 방식]

재대로 된 많은 예제들은 아래의 URL에서 찾을 수 있다. 아주 다양한 그림들을 볼 수 있다.

예제 소스 코드를 마우스로 복사하여 vi 에디터에 붙여 넣기를 할 때 옵션 설정이 중요하다.
:set paste 
옵션을 활용해야 제대로 복사할 수 있다. copy-paste 를 정확히 수행하기 위한 옵션 설정이다. 

가장 핵심이 되는 것은 리스트 두 개를 선언하는 것이다. 이들을 이용하면 쉽게 xy plot을 만들 수 있다.
첫번째 리스트가 x값들이되고 두번째 리스트가 y값들이 된다.
응용하면 파일에서 데이터를 읽어들여서 두 개의 리스트를 채우는 것이 가능하다. 이렇게 리스트들을 만들 수 있으면 준비된 데이터를 그림으로 그릴 수 있다.

예제에 따라서는 numpy를 사용하고, array를 사용할 경우가 있다.
asarray()함수를 잘 사용하면 된다.

-------------------------------------------------------------------------------------------------------------------

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mathtext as mathtext
iid=[]
volume=[]
energy=[]
kount=0
with open("csa.out1", 'r') as afile:
     for line in afile:
         if(len(line.split()) == 11 and line.split()[3] == 'outcar'):
             iid.append(int(line.split()[0]))
             volume.append(float(line.split()[1]))
             energy.append(float(line.split()[2]))
             kount=kount+1

#print kount
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
fig, ax = plt.subplots()
ax.plot(volume, energy, 'o', ms=5, lw=2, alpha=0.7, mfc='orange')
ax.grid()
ax.set_xlim(500,1000)
ax.set_ylim(-175,-150)
ax.set_xlabel('volume (\AA$^3$)', fontsize=20)
ax.set_ylabel('energy (eV)', fontsize=20)
plt.show()

-------------------------------------------------------------------------------------------------------------------

import numpy as np
import matplotlib.pyplot as plt
# Example data
t = np.arange(0.0, 1.0 + 0.01, 0.01)
s = np.cos(4 * np.pi * t) + 2

plt.rc('text', usetex=True)
plt.rc('font', family='serif')
plt.plot(t, s)

plt.xlabel(r'\textbf{time} (s)')
plt.ylabel(r'\textit{voltage} (mV)',fontsize=16)
plt.title(r"\TeX\ is Number "
          r"$\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!",
          fontsize=16, color='gray')
# Make room for the ridiculously large title.
plt.subplots_adjust(top=0.8)

plt.savefig('tex_demo')
plt.show()

-------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------








------------------------------------------------------------------------------------------------------------------
Sentdex --> 저자
matplotlib tutorial 동영상 강의 시리즈:


------------------------------------------------------------------------------------------------------------------


"""
A simple example of an animated plot
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig, ax = plt.subplots()

x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))


def animate(i):
    line.set_ydata(np.sin(x + i/10.0))  # update the data
    return line,


# Init only required for blitting to give a clean slate.
def init():
    line.set_ydata(np.ma.array(x, mask=True))
    return line,

ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init,
                              interval=25, blit=True)
plt.show()

------------------------------------------------------------------------------------------------------------------

데이터를 시간순으로 업데이트할 수 있다면, 그 데이터를 이용해서 애니메이션을 만들 수 있다.
example.txt 파일을 시간에 따라서 읽는다. 읽을 때마다 내용이 다르면 다른 그림이 그려진다.


------------------------------------------------------------------------------------------------------------------

3D plot 예제는 아래와 같이 간단하다.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1)

plt.show()

------------------------------------------------------------------------------------------------------------------


from mpl_toolkits.mplot3d.axes3d import Axes3D
from matplotlib import cm
#from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatter
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()

ax = fig.add_subplot(1, 2, 1, projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet,
        linewidth=0, antialiased=False)
ax.set_zlim3d(-1.01, 1.01)

#ax.w_zaxis.set_major_locator(LinearLocator(10))
#ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))

fig.colorbar(surf, shrink=0.5, aspect=5)

from mpl_toolkits.mplot3d.axes3d import get_test_data
ax = fig.add_subplot(1, 2, 2, projection='3d')
X, Y, Z = get_test_data(0.05)
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)

plt.show()

------------------------------------------------------------------------------------------------------------------


import matplotlib.pyplot as plt
import numpy as np

np.random.seed(19680801)
data = np.random.randn(2, 100)

fig, axs = plt.subplots(2, 2, figsize=(5, 5))
axs[0, 0].hist(data[0])
axs[1, 0].scatter(data[0], data[1])
axs[0, 1].plot(data[0], data[1])
axs[1, 1].hist2d(data[0], data[1])

plt.show()

------------------------------------------------------------------------------------------------------------------


import numpy as np
import matplotlib.pyplot as plt

# Data for plotting
t = np.arange(0.01, 20.0, 0.01)

# Create figure
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)

# log y axis
ax1.semilogy(t, np.exp(-t / 5.0))
ax1.set(title='semilogy')
ax1.grid()

# log x axis
ax2.semilogx(t, np.sin(2 * np.pi * t))
ax2.set(title='semilogx')
ax2.grid()

# log x and y axis
ax3.loglog(t, 20 * np.exp(-t / 10.0), basex=2)
ax3.set(title='loglog base 2 on x')
ax3.grid()

# With errorbars: clip non-positive values
# Use new data for plotting
x = 10.0**np.linspace(0.0, 2.0, 20)
y = x**2.0

ax4.set_xscale("log", nonposx='clip')
ax4.set_yscale("log", nonposy='clip')
ax4.set(title='Errorbars go negative')
ax4.errorbar(x, y, xerr=0.1 * x, yerr=5.0 + 0.75 * y)
# ylim must be set after errorbar to allow errorbar to autoscale limits
ax4.set_ylim(ymin=0.1)

fig.tight_layout()
plt.show()

------------------------------------------------------------------------------------------------------------------



두 가지 서로 다른 y 축 스케일을 사용할 경우:


import numpy as np
import matplotlib.pyplot as plt

# Create some mock data
t = np.arange(0.01, 10.0, 0.01)
data1 = np.exp(t)
data2 = np.sin(2 * np.pi * t)

fig, ax1 = plt.subplots()

color = 'red'
ax1.set_xlabel('time (s)')
ax1.set_ylabel('exp', color=color)
ax1.plot(t, data1, color=color)
ax1.tick_params(axis='y', labelcolor=color)

ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis

color = 'blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1
ax2.plot(t, data2, color=color)
ax2.tick_params(axis='y', labelcolor=color)

fig.tight_layout()  # otherwise the right y-label is slightly clipped
plt.show()

------------------------------------------------------------------------------------------------------------------

아래에 표시된 것들은 그림을 그릴 때 알아 두면 편리한 전문 용어들이다.
title
legend
major tick label
minor tick label
x axis label
y axis label
major tick
minor tick
grid
line
markers
spines

../../_images/anatomy.png



핑백

덧글

  • foodie 2018/07/09 00:40 # 답글

    요즘은 bokeh가 유행인 모양입니다. GNUplot 이나 R 쓰다가 Python만 오면 모듈들의 향연이... 좀 더 abstract해도 될 듯 한데 왜 이렇게 복잡하게 해 놓는 걸까요.
  • 바죠 2018/07/09 07:12 # 삭제

    제가 잘 모르는 것을 지적해 주셨습니다. 감사합니다. 말씀하신 bokeh를 찾아 보았습니다. 한 번 체클해보도록 하겠습니다.
    초심자들이 쉽게 복사해서 사용할 수 있다면, 그것도 괜찮은 선택이라고 봅니다.

    https://bokeh.pydata.org/en/latest/
    https://towardsdatascience.com/data-visualization-with-bokeh-in-python-part-one-getting-started-a11655a467d4
    https://www.datacamp.com/community/blog/bokeh-cheat-sheet-python

댓글 입력 영역

최근 포토로그