Birçoğunuz sıradan kameralarla çekilen görüntü verilerine (bilimsel literatürde sıklıkla “doğal görüntüler” olarak adlandırılır) aşinasınız; ayrıca mikroskoplar veya teleskoplar gibi özel cihazlarla elde edilenlere de. Python'da görüntülerle çalışırken, bunları görüntülemenin en yaygın yolu, Python'un en popüler çizim kütüphanesi olan Matplotlib'in imshow işlevini kullanmaktır.
Bu eğitimde, bu işlevi 3B hacimsel verileri gösterecek şekilde nasıl genişleteceğinizi göstereceğiz; bunu, bir görüntü yığını olarak düşünebilirsiniz. Birlikte ele alındıklarında 3B bir yapıyı tanımlarlar. Örneğin manyetik rezonans görüntüleme (MRI) ve bilgisayarlı tomografi (BT) taramaları, insan vücudunun içindeki 3B yapıyı ölçer; X-ışını mikrotomografisi, cam veya metal alaşımlar gibi malzemelerin içindeki 3B yapıyı ölçer; ve ışık-tabakalı mikroskoplar, biyolojik dokular içindeki floresan parçacıkları ölçer.
matplotlib kullanarak bir MRI veri setini nasıl indireceğinizi ve dilimlerini nasıl görüntüleyeceğinizi göstereceğiz. Şunları öğreneceksiniz:
NIfTI dosya formatındaki dosyalar için bir okuyucu sağlayan nibabel kütüphanesinin yardımıyla verilerinizi alma. Bu adımı atlayıp doğrudan çizime başlamak isteyenler için, bu eğitim verileri scikit-image ile nasıl alacağınızı da gösterecek.
Ardından, matplotlib’in olay işleyici API’siyle tam işlevli bir dilim görüntüleyiciye doğru ilk adımları atacak ve
Yeni aracınızdan yararlanmak için bazı kodlarınızı yeniden yazacaksınız.
Son olarak, işiniz bittiğinde çalışma alanınızı nasıl temizleyebileceğinizi göreceksiniz.
Ama önce bazı temel bilgilere bakalım: Matplotlib’in imshow işleviyle görüntüler nasıl görüntülenir.
Eğer Jupyter Notebook ile çalışıyorsanız, etkileşimli matplotlib modunu etkinleştirerek başlayabilirsiniz:
Şimdi matplotlib'i içe aktarabilir ve bazı verileri görüntüleyebilirsiniz. scikit-image kütüphanesinin data modülüne dahil edilen bazı örnek verileri yükleyeceksiniz:
import matplotlib.pyplot as plt
from skimage import data
astronaut = data.astronaut()
ihc = data.immunohistochemistry()
hubble = data.hubble_deep_field()
# Initialize the subplot panels side by side
fig, ax = plt.subplots(nrows=1, ncols=3)
# Show an image in each subplot
ax[0].imshow(astronaut)
ax[0].set_title('Natural image')
ax[1].imshow(ihc)
ax[1].set_title('Microscopy image')
ax[2].imshow(hubble)
ax[2].set_title('Telescope image');Altyapı:
Not: Matplotlib’i etkileşimli notebook modunda çalıştırdığınızda, açık şekil (figure) siz onu devre dışı bırakana kadar (şeklin sağ üstündeki güç simgesini kullanarak) etkin kalır. Her grafikten ilerlemeden önce bunu yaptığınızdan emin olun.
Bu görüntüler, 2 boyut boyunca düzenlendikleri için 2 boyutlu ya da 2D görüntüler olarak adlandırılır: x ve y ya da NumPy terminolojisiyle satırlar ve sütunlar veya r ve c.
Bazı görüntüler 3B’dir; çünkü ek bir derinlik boyutuna (z veya düzlemler) sahiptir. Bunlara manyetik rezonans görüntüleme (MRI) ve bir örneğin salam gibi ince ince dilimlendiği ve her dilimin ayrı ayrı görüntülendiği seri bölütleme transmisyon elektron mikroskopisi (ssTEM) dahildir.
Böyle görüntüleri matplotlib’de görmek için bir dilim seçip yalnızca o dilimi görüntülemeliyiz. Bunu çevrimiçi olarak serbestçe erişilebilen bazı MRI verileri üzerinde deneyelim.
Ara: Verileri Alma
Buchel ve Friston’un, Cortical Interactions Evaluated with Structural Equation Modelling and fMRI (1997) çalışmasında tanımlanan bir veri setini indireceğiz. Önce verileri indireceğimiz geçici bir dizin oluşturuyoruz. Analizimiz bittiğinde bunu silmeyi unutmamalıyız! Bu veri setini daha sonra kullanmak üzere saklamak isterseniz, d değerini seçeceğiniz daha kalıcı bir dizin konumuyla değiştirin.
import tempfile
# Create a temporary directory
d = tempfile.mkdtemp()Altyapı:
Şimdi verileri indirelim:
import os
# Return the tail of the path
os.path.basename('http://google.com/attention.zip')Altyapı:
from urllib.request import urlretrieve
# Define URL
url ='http://www.fil.ion.ucl.ac.uk/spm/download/data/attention/attention.zip'
# Retrieve the data
fn, info =urlretrieve(url, os.path.join(d,'attention.zip'))Altyapı:
Ve bunları zip dosyasından geçici dizinimize çıkaralım:
import zipfile
# Extract the contents into the temporary directory we created earlier
zipfile.ZipFile(fn).extractall(path=d)Altyapı:
Dosyanın gerçek içeriğine bakarsanız, bir sürü ‘.hdr’ ve ‘.img’ dosyası bulacaksınız.
# List first 10 files
[f.filename for f in zipfile.ZipFile(fn).filelist[:10]]Altyapı:
Bunlar NIfTI dosya formatındadır ve bunlar için bir okuyucuya ihtiyacımız olacak. Neyse ki, mükemmel nibabel kütüphanesi böyle bir okuyucu sağlıyor. Mutlaka conda install -c conda-forge nibabel ya da pip install nibabel ile yükleyin ve ardından:
Artık nihayet görüntümüzü okuyabilir ve görüntülemek için bir NumPy dizisi almak üzere .get_data() yöntemini kullanabiliriz:
# Read the image
struct = nibabel.load(os.path.join(d,'attention/structural/nsM00587_0002.hdr'))
# Get a plain NumPy array, without all the metadata
struct_arr = struct.get_data()Altyapı:
İpucu: Doğrudan MRI verilerini çizmeye devam etmek isterseniz, aşağıdaki kod satırlarını çalıştırın:
from skimage import io
struct_arr = io.imread("https://s3.amazonaws.com/assets.datacamp.com/blog_assets/attention-mri.tif")Altyapı:
Vay! Oldukça basık görünüyor! Bunun nedeni, birçok MRI’da düşey eksendeki çözünürlüğün yatay eksenlerdekinden farklı olması. Bunu, imshow işlevine aspect parametresi vererek düzeltebiliriz:
Tüm bu çağrılar kısa sürede oldukça yorucu hale geliyor. Uzun süre boyunca, 3B hacimleri Python dışında, ITK-SNAP gibi araçlarla görüntülüyordum. Ancak, meğerse matplotlib görüntüleyiciye 3B “kaydırma” yetenekleri eklemek oldukça kolaymış! Bu, 3B verileri Python içinde keşfetmemizi sağlar ve veri keşfi ile veri analizi arasında bağlam değiştirme ihtiyacını en aza indirir.
Buradaki kilit nokta, belirli tuş vuruşlarına veya fare tıklamalarına yanıt olarak grafikte yapılacak eylemleri — grafiğin verilerini değiştirmek de dahil! — tanımlamamıza olanak tanıyan matplotlibolay işleyici API’sini kullanmaktır.
Bizim durumumuzda, klavyedeki J ve K tuşlarını “önceki dilim” ve “sonraki dilim” olarak bağlayalım:
mpl_connect için tam belgeleri, hangi diğer tür olaylara bağlanabileceğinizi (ör. fare tıklamaları) da içerecek şekilde, burada bulabilirsiniz.
Biraz inceleme yaptıktan sonra, imshow’un, tüm çizimlerin gerçekleştiği matplotlib Axes nesnesinin “içinde” .images özniteliğinde bulunan bir AxesImage nesnesi döndürdüğünü öğrendim. Ve bu nesne, görüntülenen görüntü verilerini değiştiren kullanışlı bir set_array yöntemi sağlıyor! Öyleyse yapmamız gereken tek şey:
rasgele bir indisi çizmek ve bu indisi, belki de çalışma zamanında Axes nesnesine ek bir öznitelik olarak kaydetmek.
indisi değiştiren ve 3B hacmin ilgili dilimini ayarlamak için set_array kullanan next_slice ve previous_slice işlevlerini sağlamak.
yeni verilerle şekli yeniden çizmek için şekil tuvalinin draw yöntemini kullanmak.
def multi_slice_viewer(volume):
fig, ax = plt.subplots()
ax.volume = volume
ax.index = volume.shape[0]// 2
ax.imshow(volume[ax.index])
fig.canvas.mpl_connect('key_press_event', process_key)
def process_key(event):
fig = event.canvas.figure
ax = fig.axes[0]if event.key =='j':previous_slice(ax)
elif event.key =='k':next_slice(ax)
fig.canvas.draw()
def previous_slice(ax):"""Go to the previous slice."""
volume = ax.volume
ax.index =(ax.index -1)% volume.shape[0] # wrap around using %
ax.images[0].set_array(volume[ax.index])
def next_slice(ax):"""Go to the next slice."""
volume = ax.volume
ax.index =(ax.index +1)% volume.shape[0]
ax.images[0].set_array(volume[ax.index])Altyapı:
Çalıştı! Harika! Ancak bunu kendi bilgisayarınızda denerseniz, K ile yukarı kaydırmanın aynı zamanda grafiğin yatay ölçeğini de bastırdığını fark edeceksiniz. Hı? (Bu yalnızca fareniz görüntünün üzerindeyse olur.)
Olan şu ki, Matplotlib’e olay işleyicileri eklemek, onları birbirinin üzerine yığar. Bu durumda, K, x eksenini logaritmik ölçek kullanacak şekilde değiştiren yerleşik bir klavye kısayoludur. K tuşunu tamamen bize özel kullanmak istiyorsak, onu matplotlib’in varsayılan tuş eşlemelerinden kaldırmamız gerekir. Bunlar, matplotlib’in sistem genelindeki varsayılan ayarlarının deposu olan plt.rcParams sözlüğünde listeler olarak bulunur:
burada listedeki tuşlardan herhangi birine basmak (yani <key1> veya <key2>) <command> komutunun çalışmasına neden olur.
Dolayısıyla, bu sözlükte nerede görünürlerse görünsünler, kullanmak istediğimiz tuşları kaldıracak yardımcı bir işlev yazmamız gerekecek. (matplotlib’de bu işlev henüz yok, ancak muhtemelen memnuniyetle karşılanacak bir katkı olurdu!)
def remove_keymap_conflicts(new_keys_set):for prop in plt.rcParams:if prop.startswith('keymap.'):
keys = plt.rcParams[prop]
remove_list =set(keys)& new_keys_set
for key inremove_list:
keys.remove(key)Altyapı:
Tam İşlevli Bir Dilim Görüntüleyici
Tamam, bu yeni araçtan yararlanmak için işlevimizi yeniden yazalım:
Bu yöntemin güzel bir özelliği, herhangi bir matplotlib arka ucunda çalışmasıdır! Yani bunu IPython terminal konsolunda denerseniz, tarayıcıda olduğu gibi aynı etkileşimi elde edersiniz! Ve matplotlib grafiğini gömen bir Qt veya Tkinter uygulaması için de durum aynıdır. Dolayısıyla bu basit araç, matplotlib’in görselleştirme yetenekleri etrafında giderek daha karmaşık uygulamalar oluşturmanıza olanak tanır.
Gitmeden Önce
Kendimizden sonra temizlik yapmayı ve geçici dizini (oluşturduysanız) silmeyi unutmayalım:
import shutil
# Remove the temporary directory
shutil.rmtree(d)Altyapı:
Sonuç
Tebrikler! Oldukça uzun bir yolculuk oldu, ancak bu Matplotlib eğitiminin sonuna ulaştınız!
Bu serinin ikinci yazısında, alt grafiklerin ölçeklendirilmesi, her grafiğin nereden dilimlendiğini gösteren nişangâhlar ve fare etkileşimi hakkında daha fazlasını öğreneceğiniz için bizi takipte kalın.
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Birçoğunuz sıradan kameralarla çekilen görüntü verilerine (bilimsel literatürde sıklıkla “doğal görüntüler” olarak adlandırılır) aşinasınız; ayrıca mikroskoplar veya teleskoplar gibi özel cihazlarla elde edilenlere de. Python'da görüntülerle çalışırken, bunları görüntülemenin en yaygın yolu, Python'un en popüler çizim kütüphanesi olan Matplotlib'in imshow işlevini kullanmaktır.
Bu eğitimde, bu işlevi 3B hacimsel verileri gösterecek şekilde nasıl genişleteceğinizi göstereceğiz; bunu, bir görüntü yığını olarak düşünebilirsiniz. Birlikte ele alındıklarında 3B bir yapıyı tanımlarlar. Örneğin manyetik rezonans görüntüleme (MRI) ve bilgisayarlı tomografi (BT) taramaları, insan vücudunun içindeki 3B yapıyı ölçer; X-ışını mikrotomografisi, cam veya metal alaşımlar gibi malzemelerin içindeki 3B yapıyı ölçer; ve ışık-tabakalı mikroskoplar, biyolojik dokular içindeki floresan parçacıkları ölçer.
matplotlibkullanarak bir MRI veri setini nasıl indireceğinizi ve dilimlerini nasıl görüntüleyeceğinizi göstereceğiz. Şunları öğreneceksiniz:nibabelkütüphanesinin yardımıyla verilerinizi alma. Bu adımı atlayıp doğrudan çizime başlamak isteyenler için, bu eğitim verileri scikit-image ile nasıl alacağınızı da gösterecek.Ama önce bazı temel bilgilere bakalım: Matplotlib’in
imshowişleviyle görüntüler nasıl görüntülenir.Eğer Jupyter Notebook ile çalışıyorsanız, etkileşimli matplotlib modunu etkinleştirerek başlayabilirsiniz:
Şimdi
matplotlib'i içe aktarabilir ve bazı verileri görüntüleyebilirsiniz. scikit-image kütüphanesinin data modülüne dahil edilen bazı örnek verileri yükleyeceksiniz:Not: Matplotlib’i etkileşimli notebook modunda çalıştırdığınızda, açık şekil (figure) siz onu devre dışı bırakana kadar (şeklin sağ üstündeki güç simgesini kullanarak) etkin kalır. Her grafikten ilerlemeden önce bunu yaptığınızdan emin olun.
Bu görüntüler, 2 boyut boyunca düzenlendikleri için 2 boyutlu ya da 2D görüntüler olarak adlandırılır: x ve y ya da NumPy terminolojisiyle satırlar ve sütunlar veya r ve c.
Bazı görüntüler 3B’dir; çünkü ek bir derinlik boyutuna (z veya düzlemler) sahiptir. Bunlara manyetik rezonans görüntüleme (MRI) ve bir örneğin salam gibi ince ince dilimlendiği ve her dilimin ayrı ayrı görüntülendiği seri bölütleme transmisyon elektron mikroskopisi (ssTEM) dahildir.
Böyle görüntüleri matplotlib’de görmek için bir dilim seçip yalnızca o dilimi görüntülemeliyiz. Bunu çevrimiçi olarak serbestçe erişilebilen bazı MRI verileri üzerinde deneyelim.
Ara: Verileri Alma
Buchel ve Friston’un, Cortical Interactions Evaluated with Structural Equation Modelling and fMRI (1997) çalışmasında tanımlanan bir veri setini indireceğiz. Önce verileri indireceğimiz geçici bir dizin oluşturuyoruz. Analizimiz bittiğinde bunu silmeyi unutmamalıyız! Bu veri setini daha sonra kullanmak üzere saklamak isterseniz,
ddeğerini seçeceğiniz daha kalıcı bir dizin konumuyla değiştirin.Şimdi verileri indirelim:
Ve bunları
zipdosyasından geçici dizinimize çıkaralım:Dosyanın gerçek içeriğine bakarsanız, bir sürü ‘.hdr’ ve ‘.img’ dosyası bulacaksınız.
Bunlar NIfTI dosya formatındadır ve bunlar için bir okuyucuya ihtiyacımız olacak. Neyse ki, mükemmel
nibabelkütüphanesi böyle bir okuyucu sağlıyor. Mutlakaconda install -c conda-forge nibabelya dapip install nibabelile yükleyin ve ardından:Artık nihayet görüntümüzü okuyabilir ve görüntülemek için bir NumPy dizisi almak üzere
.get_data()yöntemini kullanabiliriz:İpucu: Doğrudan MRI verilerini çizmeye devam etmek isterseniz, aşağıdaki kod satırlarını çalıştırın:
Yeniden Çizime Dönelim
Şimdi bu dizideki bir dilime bakalım:
Vay! Oldukça basık görünüyor! Bunun nedeni, birçok MRI’da düşey eksendeki çözünürlüğün yatay eksenlerdekinden farklı olması. Bunu,
imshowişlevineaspectparametresi vererek düzeltebiliriz:Ama işleri kolaylaştırmak için verileri transpoze edeceğiz ve yalnızca yatay dilimlere bakacağız; böyle ayarlamalara gerek kalmaz.
Güzel! Elbette, başka bir dilimi veya farklı bir eksen boyunca bir dilimi görmek için,
imshow’u yeniden çağırmamız gerekir:Tüm bu çağrılar kısa sürede oldukça yorucu hale geliyor. Uzun süre boyunca, 3B hacimleri Python dışında, ITK-SNAP gibi araçlarla görüntülüyordum. Ancak, meğerse matplotlib görüntüleyiciye 3B “kaydırma” yetenekleri eklemek oldukça kolaymış! Bu, 3B verileri Python içinde keşfetmemizi sağlar ve veri keşfi ile veri analizi arasında bağlam değiştirme ihtiyacını en aza indirir.
Buradaki kilit nokta, belirli tuş vuruşlarına veya fare tıklamalarına yanıt olarak grafikte yapılacak eylemleri — grafiğin verilerini değiştirmek de dahil! — tanımlamamıza olanak tanıyan
matplotlibolay işleyici API’sini kullanmaktır.Bizim durumumuzda, klavyedeki J ve K tuşlarını “önceki dilim” ve “sonraki dilim” olarak bağlayalım:
Yeterince basit! Elbette, bu eylemleri gerçekte nasıl uygulayacağımızı bulmamız ve şekle, klavye tuşlarına basmaları işlemek için
process_keyişlevini kullanması gerektiğini söylememiz gerekiyor! İkincisi basit: şekil tuvali üzerindempl_connectyöntemini kullanmamız yeterli:mpl_connectiçin tam belgeleri, hangi diğer tür olaylara bağlanabileceğinizi (ör. fare tıklamaları) da içerecek şekilde, burada bulabilirsiniz.Biraz inceleme yaptıktan sonra,
imshow’un, tüm çizimlerin gerçekleştiği matplotlibAxesnesnesinin “içinde”.imagesözniteliğinde bulunan birAxesImagenesnesi döndürdüğünü öğrendim. Ve bu nesne, görüntülenen görüntü verilerini değiştiren kullanışlı birset_arrayyöntemi sağlıyor! Öyleyse yapmamız gereken tek şey:Axesnesnesine ek bir öznitelik olarak kaydetmek.set_arraykullanannext_sliceveprevious_sliceişlevlerini sağlamak.drawyöntemini kullanmak.Hadi deneyelim!
Çalıştı! Harika! Ancak bunu kendi bilgisayarınızda denerseniz, K ile yukarı kaydırmanın aynı zamanda grafiğin yatay ölçeğini de bastırdığını fark edeceksiniz. Hı? (Bu yalnızca fareniz görüntünün üzerindeyse olur.)
Olan şu ki, Matplotlib’e olay işleyicileri eklemek, onları birbirinin üzerine yığar. Bu durumda, K, x eksenini logaritmik ölçek kullanacak şekilde değiştiren yerleşik bir klavye kısayoludur. K tuşunu tamamen bize özel kullanmak istiyorsak, onu
matplotlib’in varsayılan tuş eşlemelerinden kaldırmamız gerekir. Bunlar,matplotlib’in sistem genelindeki varsayılan ayarlarının deposu olanplt.rcParamssözlüğünde listeler olarak bulunur:burada listedeki tuşlardan herhangi birine basmak (yani
<key1>veya<key2>)<command>komutunun çalışmasına neden olur.Dolayısıyla, bu sözlükte nerede görünürlerse görünsünler, kullanmak istediğimiz tuşları kaldıracak yardımcı bir işlev yazmamız gerekecek. (
matplotlib’de bu işlev henüz yok, ancak muhtemelen memnuniyetle karşılanacak bir katkı olurdu!)Tam İşlevli Bir Dilim Görüntüleyici
Tamam, bu yeni araçtan yararlanmak için işlevimizi yeniden yazalım:
Artık, varsayılan tuş eşlemelerinden kaynaklanan can sıkıcı müdahaleler olmadan MRI hacmimizdeki tüm dilimleri görüntüleyebilmeliyiz!
Bu yöntemin güzel bir özelliği, herhangi bir matplotlib arka ucunda çalışmasıdır! Yani bunu IPython terminal konsolunda denerseniz, tarayıcıda olduğu gibi aynı etkileşimi elde edersiniz! Ve matplotlib grafiğini gömen bir Qt veya Tkinter uygulaması için de durum aynıdır. Dolayısıyla bu basit araç, matplotlib’in görselleştirme yetenekleri etrafında giderek daha karmaşık uygulamalar oluşturmanıza olanak tanır.
Gitmeden Önce
Kendimizden sonra temizlik yapmayı ve geçici dizini (oluşturduysanız) silmeyi unutmayalım:
Sonuç
Tebrikler! Oldukça uzun bir yolculuk oldu, ancak bu Matplotlib eğitiminin sonuna ulaştınız!
Bu serinin ikinci yazısında, alt grafiklerin ölçeklendirilmesi, her grafiğin nereden dilimlendiğini gösteren nişangâhlar ve fare etkileşimi hakkında daha fazlasını öğreneceğiniz için bizi takipte kalın.
DataCamp'in Matplotlib Eğitimi: Python Plotlama sayfasına göz atın.
Python’da veri görselleştirme hakkında daha fazla bilgi edinmek isterseniz, DataCamp’in Introduction to Data Visualization in Python kursunu değerlendirin.