Yükseklik Verisini Kontur olarak Folium Haritasında Göstermek
Matplotlib'de contour
komutu x,y
ızgarasında üç boyutta yükseklik
olarak kabul edilebilecek z
verisini "kuşbakışı" olarak
gösterebilen, kesit seviyelerini, bir nevi topografik haritayı
hesaplabilen bir komuttur. Peki bu seviyeleri alıp Matplotlib ile
direk bağlantısı olmayan Folium [3] haritalarına taşımak istesek bunu
nasıl yaparız? Üç boyutlu yükseklik verisini iki boyutlu kesit
seviyelerine dönüştürmek kolay değil, contour
içindeki kodu bu iş
için kullansak tekrar yazmaya gerek kalmazdı. Bunu yapmak mümkün,
çünkü contour
bize seviyeleri temsil eden parçaları dondürebiliyor.
Örnek üzerinde görelim. Belli x,y
değerleri arasında bir ızgara
yaratalım (bu değerler TR haritasında özel bir yere tekabül edecek
şekilde seçildi, ki sonra Folium'da gösterim yapabilelim), ve ızgaraya
bir tane "tepe" koyalım, bunu iki degiskenli (bivariate, ve üç
boyutlu) Gaussian fonksiyonu ile yapabiliyoruz, ve kesit seviyelerini
gösterelim,
import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'
def bivariate_normal(X, Y, sigmax=1.0, sigmay=1.0,
mux=0.0, muy=0.0, sigmaxy=0.0):
Xmu = X-mux
Ymu = Y-muy
rho = sigmaxy/(sigmax*sigmay)
z = Xmu**2/sigmax**2 + Ymu**2/sigmay**2 - 2*rho*Xmu*Ymu/(sigmax*sigmay)
denom = 2*np.pi*sigmax*sigmay*np.sqrt(1-rho**2)
return np.exp(-z/(2*(1-rho**2))) / denom
delta = 0.025
x = np.arange(29.06161, 29.20870, delta)
y = np.arange(36.61599, 36.70624, delta)
X, Y = np.meshgrid(x, y)
Z = 10*bivariate_normal(X, Y, 0.02, 0.02, 29.13920, 36.64653)
plt.figure()
CS = plt.contour(X, Y, Z )
plt.clabel(CS, inline=1, fontsize=10)
plt.savefig('elev1.png')
Sanki bir "dağa" üstten bakıyoruz, dağın eteklerinde 500 metre yükseklik var, sonra giderek yükseliyor, ve en tepede 3000 metreye ulaşıyoruz.
Üstteki grafiği oluşturan ham bilgilere erişmek mümkün. Gördüğümüz
gibi çağrıyı CS = plt.contour
ile yaptık, döndürülen CS
içinde
gerekli bilgiler var. Bu bilgiler bölümler (segments) olarak
tutulmuş, mesela
print (CS.levels)
[ 0. 500. 1000. 1500. 2000. 2500. 3000. 3500. 4000.]
print (len(CS.allsegs))
9
sonucunu verir. 1'inci bölümdeki 0'ıncı alt bölümde,
CS.allsegs[1][0]
Out[1]:
array([[29.16850299, 36.61599 ],
[29.18289603, 36.64099 ],
[29.17913935, 36.66599 ],
[29.16161 , 36.68398265],
[29.13661 , 36.68902999],
[29.11161 , 36.67980347],
[29.0986095 , 36.66599 ],
[29.09359308, 36.64099 ],
[29.11161 , 36.61651895],
[29.11231435, 36.61599 ]])
görülüyor. İşte bu noktalar kesit seviyelerini oluşturan çizgilerin baş ve son noktaları. Eğer o çizgileri ayrı ayrı kendimiz çizmek istesek,
plt.figure()
CS = plt.contour(X, Y, Z)
for i in range(len(CS.allsegs)):
for li in range(len(CS.allsegs[i])):
x = CS.allsegs[i][li][:,0]
y = CS.allsegs[i][li][:,1]
plt.plot(x,y,'r-')
plt.savefig('elev3.png')
Aynı grafiği Folium ile yapmak için,
import folium
clat,clon=36.64653, 29.13920
m = folium.Map(location=[clat, clon], zoom_start=11, tiles="Stamen Terrain")
for i in range(len(CS.allsegs)):
for li in range(len(CS.allsegs[i])):
points = []
x = CS.allsegs[i][li][:,0]
y = CS.allsegs[i][li][:,1]
for lon,lat in zip(x,y): points.append([lat,lon])
folium.PolyLine(points, color='red', weight=1.0, opacity=1).add_to(m)
m.save('elev.html')
Sonuçlar şurada görülebilir.
Yükseklik verilerini alma tekniklerini [4]'te göstermiştik; bir bölgedeki yükseklik verisini, sonra o veriyi kullanıp daha yüksek çözünürlü yükseklik verisini aradeğerleme ile hesaplama teknikleri o yazıda bulunabilir.
Kaynaklar
[1] [Tutorialspoint](https://www.tutorialspoint.com/how-to-get-coordinates-from-the-contour-in-matplotlib)
[2] [Stackoverflow](https://stackoverflow.com/questions/19418901/get-coordinates-from-the-contour-in-matplotlib)
[3] [Haritalamak](../../2020/02/haritalamak.html)
[4] [Yükseklik (Elevation) Verileri](../../2019/04/elevation.html)
Yukarı