Tuesday, January 18, 2011

Matristeki Z Degerlerini 3 Boyutta Gostermek

Elimizde bir u matrisinin oldugunu dusunelim, ki bu matris bir u(x,y) fonksiyonunun ayriksal (discrete) temsili olsun. 3 boyutta bu grafik hizli bir sekilde nasil basilir?

u(x,y) basit olarak z kordinatini temsil ediyor olacak. Peki ax.plot cagrisi icin gereken xs, ys degerleri nedir? Bu degerler u matrisinin kordinatlari olarak farzedilebilir. u[1,2] degeri zs olursa, xs=1, ys=2 kabul edilir. Alttaki ornekte u "fonksiyonu" 3d grafigin en ust katmaninda 8 genisligindeki bir "dis bantta" 4 degerini tasiyor, diger her yerde, yani ic bantlarda asagi dogru iniyor, -4 degerini tasiyor. Ortaya cikan grafik bir konveks sekle sahip, alti cukur (ve ici bos) olan bir cisim. 3 boyutta grafiklemek icin su yeterli:

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

def plot_u(u):
fig = plt.figure()
ax = Axes3D(fig)
x = []
y = []
for (i,j),val in np.ndenumerate(u):
x.append(i)
y.append(j)
ax.plot(xs=x, ys=y, zs=u.flatten(), zdir='z', label='ys=0, zdir=z')
plt.show()



Bu grafiklemenin islemesinin puf noktasi surada: ndenumerate ile gezerken elde ettigimiz x,y degerleri u.flatten() ile elde edilen degerlere aynen tekabul ediyor (demek ki iki Python cagrisi benzer sekilde yazilmislar). Eger boyle bir direk eslesme olmasaydi, ustteki grafikleme metodu ise yaramazdi.

Matplotlib ile Hareketli Grafikler

Robotik hakkinda bir yazida, baska seylerle beraber daha once bahsetmistik, ama daha detayli olarak; Python Matplotlib ile akici, interaktif grafikler kodlamasinin kalibi soyle.

import matplotlib.pyplot as plt
plt.ion()

arkasindan, akisini istedigimiz veri cercevesinde bir donguyle (for, while, vs) plt uzerinde istedigimiz cizim cagrilarini teker teker yapiyoruz, ilk cizim sonrasi plt.hold(True) cagiriyoruz. Dongude mesela plt.imshow ile bir bitmap grafigi gosterebiliriz, plt.hold(True) sonrasi bir plt.contour cagrisi yapabiliriz, sonra bir plt.plot yapabiliriz vs.

Bir "kare" bittikten sonra en sonunda plt.draw cagrisi yapariz (dikkat, plt.show degil). "Video" akisi biraz yavaslasin istiyorsak (en basta) import time, ve yavaslik istedigimiz yerde time.sleep(saniye) ile suni gecikmeyi ekleriz. Cizim, bekleme bittikten sonra bu ekrani "silmek" icin plt.hold(False) cagiririz.

Kalip soyle:
import matplotlib.pyplot as plt
import time

plt.ion()

for .. in range(...):
plt.imshow(..)
plt.hold(True)
CS = plt.contour(..)
plt.plot(..)
...
plt.draw()
time.sleep(1)
plt.hold(False)