본문 바로가기

Software/Python

Python Matplotlib를 이용해서 간단하게 GUI의 슬라이더, 라디오버튼, 버튼을 구현하는 예제

아주 예전에 간단히 Python으로 뭔가 작업을 하다가, 정말 심플하게 GUI에서 이야기하는 슬라이더가 필요했었던 적이 있습니다. 그 때 공부했던 내용인데요... 뭐 거창한 GUI 환경을 구축하는 것이 아니라, 그저 간단하게 현재 그래프를 보면서 뭔가 GUI틱한 일을 하고 싶을 때 쓰는 용도입니다. 그 중에서 슬라이더와 라디오버튼과 버튼에 대해 알아볼려구요.^.^ 이 예제는 matplotlib.org에서 배포하는 예제입니다.^^.

일단 저는 설명을 위해 살짝... 나눠서 설명해야겠어요^^

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t, s, lw=2, color='red')
plt.axis([0, 1, -10, 10])

plt.show()

먼저 위 코드는 그저.. 심플하게 사인파 하나 그려본 겁니다.

subplot_adjust로 버튼과 슬라이더가 위치할 공간을 잡은것 빼고는 일상적인 plot입니다.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t, s, lw=2, color='red')

plt.axis([0, 1, -10, 10])
axcolor = 'lightgoldenrodyellow'

''' Add RadioButtons '''
rax = plt.axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor)
radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0)
# axes(rect) -> rect : left, bottom, width, height

def colorfunc(label):
    l.set_color(label)
    fig.canvas.draw_idle()
radio.on_clicked(colorfunc)

plt.show()

이제 위에 나타나 있듯이 RadioButton을 추가해보는 코드입니다. 먼저 버튼들이 위치할 공간을 잡고, 라디오버튼의 기능을 정의해는 거죠. 아.. axis는 [x_min, x_max, y_min, y_max]입니다만, axes는 주석에도 있듯이 [left, bottom, width, height]입니다. 결국 RadioButtons에서 선택된 값을 가지고 뭔가 일을 하는 아이는 colorfunc이라는 함수입니다. radio.on_clicked에서 colorfunc을 실행하도록 하고 있네요. 그 함수는 그래프의 색상을 변경하도록 하고 있습니다.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

fig = plt.figure()
plt.subplots_adjust(left=0.25, bottom=0.25)

t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t, s, lw=2, color='red')

plt.axis([0, 1, -10, 10])
axcolor = 'lightgoldenrodyellow'

''' Add Slider '''

axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
axamp = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
# axes(rect) -> rect : left, bottom, width, height

sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)

def update(val):
    amp = samp.val
    freq = sfreq.val
    l.set_ydata(amp*np.sin(2*np.pi*freq*t))
    fig.canvas.draw_idle()

sfreq.on_changed(update)
samp.on_changed(update)

''' Add RadioButtons '''

rax = plt.axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor)
radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0)

def colorfunc(label):
    l.set_color(label)
    fig.canvas.draw_idle()
radio.on_clicked(colorfunc)

plt.show()

이제 슬라이더를 추가하는 코드입니다. 역시 슬라이드의 위치를 axes로 잡고, 슬라이도(Slider)로 선언합니다. 이때, 실행될 함수도 선언하고, min, max값도 선언하고, 초기치(valinit)도 정해줍니다. 

위와 같이 만들어 지네요... 주기와 진폭을 지정하도록 하고 있습니다.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

fig = plt.figure()
plt.subplots_adjust(left=0.25, bottom=0.25)

t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t, s, lw=2, color='red')

plt.axis([0, 1, -10, 10])
axcolor = 'lightgoldenrodyellow'

''' Add Slider '''

axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
axamp = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
# axes(rect) -> rect : left, bottom, width, height

sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)

def update(val):
    amp = samp.val
    freq = sfreq.val
    l.set_ydata(amp*np.sin(2*np.pi*freq*t))
    fig.canvas.draw_idle()

sfreq.on_changed(update)
samp.on_changed(update)

''' Add RadioButtons '''

rax = plt.axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor)
radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0)

def colorfunc(label):
    l.set_color(label)
    fig.canvas.draw_idle()
radio.on_clicked(colorfunc)

''' Add Button '''
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')

def reset(event):
    sfreq.reset()
    samp.reset()
button.on_clicked(reset)


plt.show()

이제 전체 코드이자, 버튼을 추가한 것입니다. 똑같이 버튼이 위치할 axes를 잡고, button.on_clicked 함수로 버튼이 눌러졌을때, 수행할 함수를 잡아주구요... 그 함수는 삼각함수의 진폭과 주파수를 reset하는 역할을 하는 것이네요^^ 뭐 아무튼.. Python에서 Matplotlib를 이용해서 figure에다가 살짝 간단한 GUI를 입히는 예제를 보고 살짝 설명을 추가했습니다^^

반응형