Imshow: kapsam ve yön


86

Bir 3D veri kümesi aracılığıyla dilimleri ve projeksiyonları görselleştiren bir yazılım sistemi yazıyorum. Analiz kodumdan aldığım görüntü arabelleklerini görselleştirmek için matplotlibözellikle kullanıyorum imshow.

Görüntülere çizim eksenleri ile açıklama eklemek istediğim için imshow, görüntü arabelleği piksel koordinatlarını bir veri alanı koordinat sistemine eşlemek için sağlayan genişlik anahtar sözcüğünü kullanıyorum .

Ne yazık ki, matplotlibbirimler hakkında bir şey bilmiyor. (Yapay bir örnek alarak) şu boyutlara sahip bir görüntüyü çizmek istediğimi söyleyin.1000 m X 1 km . Bu durumda kapsam gibi bir şey olacaktır [0, 1000, 0, 1]. Görüntü dizisi kare olmasına rağmen, ölçüt anahtar kelimesinin ima ettiği en boy oranı 1000 olduğu için, ortaya çıkan çizim eksenlerinin de en boy oranı 1000'dir.

Genişlik anahtar sözcüğünü kullanarak aldığım otomatik olarak oluşturulan büyük çentik işaretlerini ve etiketleri korurken grafiğin en-boy oranını zorlamak mümkün müdür?

Yanıtlar:


144

Görüntünün boyutunu manuel olarak ayarlayarak (veya şeklin kapsamını doldurması için otomatik ölçeklendirmesine izin vererek) yapabilirsiniz.

Varsayılan olarak, imshowçizimin boyutunu 1 olarak ayarlar, çünkü bu genellikle insanların görüntü verileri için istediği şeydir.

Senin durumunda şöyle bir şey yapabilirsin:

import matplotlib.pyplot as plt
import numpy as np

grid = np.random.random((10,10))

fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, figsize=(6,10))

ax1.imshow(grid, extent=[0,100,0,1])
ax1.set_title('Default')

ax2.imshow(grid, extent=[0,100,0,1], aspect='auto')
ax2.set_title('Auto-scaled Aspect')

ax3.imshow(grid, extent=[0,100,0,1], aspect=100)
ax3.set_title('Manually Set Aspect')

plt.tight_layout()
plt.show()

görüntü açıklamasını buraya girin


Teşekkürler. Doktorların scalarseçenek hakkında hiçbir şey söylememesi tuhaf . y-axisVerilen skalere göre ölçekleniyor gibi görünüyor .
orodbhen

@JoeKington, tek tek piksellerin boyutunu elde etmek mümkündür. Bu boyut, veri kümesinin boyutuna bağlıdır ve sizin durumunuzdaki gibi sürekli bir grafiğe bir yama parçası oluşturabilir.
Alexander Cska

4

Gönderen plt.imshow()resmi kılavuz, biz bu yönü kumandaları eksenlerinin boy oranını biliyoruz. Benim sözlerime göre, en boy oranı tam olarak x birimi ve y biriminin oranıdır . Rakamları istemeden deforme etmek istemediğimiz için çoğu zaman 1 olarak tutmak isteriz. Ancak, görünüşü 1'den başka bir değer belirlememiz gereken durumlar vardır. Soru soran kişi, x ve y ekseninin farklı fiziksel birimlere sahip olabileceğine dair iyi bir örnek sağlamıştır. X'in km cinsinden ve y'nin m cinsinden olduğunu varsayalım. Bu nedenle, 10x10 verisi için, genişlik [0,10km, 0,10m] = [0, 10000m, 0, 10m] olmalıdır. Böyle bir durumda, varsayılan en boy oranını = 1 kullanmaya devam edersek, şeklin kalitesi gerçekten kötüdür. Dolayısıyla, rakamımızı optimize etmek için en boy = 1000 belirtebiliriz. Aşağıdaki kodlar bu yöntemi göstermektedir.

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
rng=np.random.RandomState(0)
data=rng.randn(10,10)
plt.imshow(data, origin = 'lower',  extent = [0, 10000, 0, 10], aspect = 1000)

görüntü açıklamasını buraya girin

Yine de, soruyu soranın talebini karşılayabilecek bir alternatif olduğunu düşünüyorum. Genişliği [0,10,0,10] olarak ayarlayabilir ve birimleri belirtmek için ek xy ekseni etiketleri ekleyebiliriz. Aşağıdaki kodlar.

plt.imshow(data, origin = 'lower',  extent = [0, 10, 0, 10])
plt.xlabel('km')
plt.ylabel('m')

görüntü açıklamasını buraya girin

Bir yapmak için doğru rakam, her zaman akılda ki taşımalıdır x_max-x_min = x_res * data.shape[1]ve y_max - y_min = y_res * data.shape[0]nerede extent = [x_min, x_max, y_min, y_max]. Varsayılan olarak, aspect = 1birim pikselin kare olduğu anlamına gelir. Bu varsayılan davranış, farklı değerlere sahip x_res ve y_res için de iyi çalışır. Önceki örneği genişleterek, x_res'in 1.5 ve y_res'in 1 olduğunu varsayalım. Dolayısıyla, kapsam [0,15,0,10] 'a eşit olmalıdır. Varsayılan en boy oranını kullanarak, dikdörtgen renkli piksellere sahip olabiliriz, oysa birim piksel hala karedir!

plt.imshow(data, origin = 'lower',  extent = [0, 15, 0, 10])
# Or we have similar x_max and y_max but different data.shape, leading to different color pixel res.
data=rng.randn(10,5)
plt.imshow(data, origin = 'lower',  extent = [0, 5, 0, 5])

görüntü açıklamasını buraya girin görüntü açıklamasını buraya girin

Renk pikselinin yönü x_res / y_res. en boyunu birim piksel boyutuna ayarlamak (yani aspect = x_res / y_res = ((x_max - x_min) / data.shape[1]) / ((y_max - y_min) / data.shape[0])) her zaman kare renkli piksel verecektir. En boy = 1.5'i değiştirebiliriz, böylece x ekseni birimi 1.5 kez y ekseni birimi olur, bu da kare renkli bir piksele ve kare tam şekle ancak dikdörtgen piksel birimine yol açar. Görünüşe göre normalde kabul edilmiyor.

data=rng.randn(10,10)
plt.imshow(data, origin = 'lower',  extent = [0, 15, 0, 10], aspect = 1.5)

görüntü açıklamasını buraya girin

En istenmeyen durum, en boy oranını 1.2 gibi rastgele bir değere ayarlamaktır; bu, ne kare birim piksellere ne de kare renkli piksellere yol açmaz.

plt.imshow(data, origin = 'lower',  extent = [0, 15, 0, 10], aspect = 1.2)

görüntü açıklamasını buraya girin

Uzun lafın kısası, doğru kapsamı belirlemek ve matplotlib'in bizim için kalan şeyleri yapmasına izin vermek her zaman yeterlidir (x_res! = Y_res olsa bile)! Görünümü yalnızca bir zorunluluk olduğunda değiştirin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.