2012-03-28 71 views
5

我想在python中使用matplotlib繪製一個小圖像,並希望顯示的軸與它生成的numpy數組具有相同的形狀,即數據不應該重新採樣。換句話說,數組中的每個條目都應該對應屏幕上的一個像素(或其附近)。這似乎微不足道,但即使拖網而互聯網之後,我似乎無法得到它的工作:matplotlib繪製沒有重新採樣的小圖像

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.cm as cm 

X = np.random.rand(30,40) 

fig = plt.figure() 
fig.add_axes(aspect="equal",extent=[0, X.shape[1], 0, X.shape[0]]) 
ax = fig.gca() 
ax.autoscale_view(True, False, False) 
ax.imshow(X, cmap = cm.gray) 

plt.show() 
+2

看起來像您提供的代碼可以達到您想要的效果,矩形形狀(40x30)在繪製圖像中保留,並且軸限制與圖像形狀相匹配。我錯過了你的問題嗎? – gcalmettes 2012-03-28 15:55:17

+0

對不起,我的措辭令人困惑。我感興趣的是像matlab中的imshow功能,其中屏幕上的像素數與矩陣中的條目數相匹配,即軸不會重新採樣以匹配數字大小。 – user588241 2012-03-28 15:59:31

+1

你的意思是沒有插值的圖像?如果是這樣,只需用'matshow'改變你的代碼'imshow',或者添加'interpolation ='nearest''作爲imshow函數的參數。 – carla 2012-03-28 16:13:01

回答

5

我自己也有同樣的問題。如果interpolation='nearest'選項imshow不夠好,那麼如果您的主要目標是在matplotlib中查看原始的,未縮放的,未插值的,未混淆的像素,則無法擊敗figimage恕我直言。演示:

import numpy as np 
import numpy.random 
import matplotlib.pyplot as plt 

a=256*np.random.rand(64,64) 

f0=plt.figure() 
plt.imshow(a,cmap=plt.gray()) 
plt.suptitle("imshow") 

f1=plt.figure() 
plt.figimage(a,cmap=plt.gray()) 
plt.suptitle("figimage") 

plt.show() 

當然,這意味着放棄軸(或自己繪製它們)。有一些figimage的選項可讓您將圖像移動到圖形的周圍,因此我認爲可以在通過其他方式創建的某些軸的頂部操縱它們。

+1

如果有人想知道,除了Ipython Notebook中的圖像之外,只有在plt.show()之前添加一個空的(「關閉的」)座標軸集合才能讓figimage工作, ,類似於這個S/O後:http://stackoverflow.com/questions/9295026/matplotlib-plots-removing-axis-legends-and-white-spaces。否則,它只是沒有繪製任何東西。 – 2013-07-17 22:31:53

1

我不知道我完全理解你的問題。這是否意味着你想要0到X.shape [1]之間的x軸和0到X.shape [0]之間的y軸?在這種情況下,該代碼應該做的伎倆:

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.cm as cm 

X = np.random.rand(30,40) 

fig = plt.figure() 

plt.xlim(0, X.shape[1]) 
plt.ylim(0, X.shape[0]) 

ax = fig.gca() 
ax.autoscale_view(True, False, False) 
ax.imshow(X, cmap = cm.gray) 

plt.show() 

希望它可以幫助

+0

謝謝,如果我的問題很混亂,我很抱歉。我試圖在Matlab中做類似imshow的事情,圖中的軸與數組的大小相同,例如,屏幕上的每個像素對應於矩陣中的條目。上述重新調整和重新採樣數組以匹配數字大小。 – user588241 2012-03-28 15:53:46

+0

我剛剛在stackoverflow上發現了一篇貼文,他們使用imshow的插值參數:ax.imshow(X,cmap = cm.gray,extent =(0,X.shape [1],0,X.shape [0] ),interpolation ='nearest')這裏是鏈接http:// stackoverflow。com/questions/6323737/make-a-2d-pixel-plot-with-matplotlib – nay 2012-03-28 16:33:56

+0

謝謝,使用最近鄰居插值是好的,但我也希望座標軸很小,也就是說它更貼近地反映真實的大小陣列。目前看起來軸線仍然重新調整以匹配數字大小。 – user588241 2012-03-28 17:14:11

1

如果你知道你的圖像的原始分辨率,可以將DPI參數設置爲你希望在什麼plt.figure(dpi=value)

您可以在此link上找到有關調整圖像大小的更多信息。

3

您可以使用下面的代碼片段將數組轉換爲PIL(Python Imaging Library)。生成的圖像將與輸入數組具有相同的大小。它可以顯示或保存爲圖像。

from PIL import Image 
from numpy import linspace, array, fromfunction, sin, cos 
from matplotlib import cm 


# scale array between vmin and vmax and encode it to uint8 (256 values) 
def scale(arr, vmin, vmax): 
    return (255*(arr - vmin)/(vmax - vmin)).clip(0, 255).astype('uint8') 

# convert a matplotlib colormap into a PIL palette 
def getpalette(cmap): 
    return (255.*array(map(lambda x: cmap(x)[0:3], linspace(0., 1.,256))).ravel()).astype('int') 


# a sample array 
data = fromfunction(lambda i,j: cos((i+j)/50)*sin(i/50.), (200, 300), dtype='float') 

# convert the float array to a PIL image 
im = Image.fromarray(scale(data, 0, 1)) 
im.putpalette(getpalette(cm.jet)) 
im.save('test.png') # or im.show() 

的唯一的事情就是im.show()不是很好,因爲它需要有圖像瀏覽器xv,並將其寫入一個臨時圖像。所以你可以編寫一個文件並用你最喜歡的圖像查看器加載它。