2010-01-08 78 views
19

我有一系列(x,y)值,我想繪製使用python的matplotlib的二維直方圖。使用hexbin,我得到的是這樣的: alt text http://img121.imageshack.us/img121/1339/hexbin.png 但是我正在尋找這樣的事情: alt text http://img17.imageshack.us/img17/1927/recthist.png 示例代碼:python matplotlib矩形binning

from matplotlib import pyplot as plt 
import random 

foo = lambda : random.gauss(0.0,1.0) 

x = [foo() for i in xrange(5000)] 
y = [foo() for i in xrange(5000)] 

pairs = zip(x,y) 

#using hexbin I supply the x,y series and it does the binning for me 
hexfig = plt.figure() 
hexplt = hexfig.add_subplot(1,1,1) 
hexplt.hexbin(x, y, gridsize = 20) 

#to use imshow I have to bin the data myself 
def histBin(pairsData,xbins,ybins=None): 
    if (ybins == None): ybins = xbins 
    xdata, ydata = zip(*pairsData) 
    xmin,xmax = min(xdata),max(xdata) 
    xwidth = xmax-xmin 
    ymin,ymax = min(ydata),max(ydata) 
    ywidth = ymax-ymin 
    def xbin(xval): 
     xbin = int(xbins*(xval-xmin)/xwidth) 
     return max(min(xbin,xbins-1),0) 
    def ybin(yval): 
     ybin = int(ybins*(yval-ymin)/ywidth) 
     return max(min(ybin,ybins-1),0) 
    hist = [[0 for x in xrange(xbins)] for y in xrange(ybins)] 
    for x,y in pairsData: 
     hist[ybin(y)][xbin(x)] += 1 
    extent = (xmin,xmax,ymin,ymax) 
    return hist,extent 

#plot using imshow 
imdata,extent = histBin(pairs,20) 
imfig = plt.figure() 
implt = imfig.add_subplot(1,1,1) 
implt.imshow(imdata,extent = extent, interpolation = 'nearest') 

plt.draw() 
plt.show() 

好像應該已經有一個辦法做到這一點,而無需編寫我的擁有「分箱」方法並使用imshow。

回答

12

numpy的有一個叫histogram2d功能,它的文檔字符串還說明了如何使用Matplotlib對其進行可視化。添加interpolation=nearest到imshow調用來禁用插值。

0

matplotlib.pyplot.hist你在找什麼?

>>> help(matplotlib.pyplot.hist) 
Help on function hist in module matplotlib.pyplot: 

hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, botto 
m=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=Fa 
lse, hold=None, **kwargs) 
    call signature:: 

     hist(x, bins=10, range=None, normed=False, cumulative=False, 
      bottom=None, histtype='bar', align='mid', 
      orientation='vertical', rwidth=None, log=False, **kwargs) 

    Compute and draw the histogram of *x*. The return value is a 
    tuple (*n*, *bins*, *patches*) or ([*n0*, *n1*, ...], *bins*, 
    [*patches0*, *patches1*,...]) if the input contains multiple 
    data. 
+0

這是一維的。我正在尋找一個二維直方圖,類似於什麼imshow()或hexbin() – job 2010-01-09 01:17:22

+0

* hist *可以做2D數據,除非我沒有明白你的觀點。如果您發佈了一些示例數據,那可能會有所幫助。 – Seth 2010-01-09 08:26:50

+2

Hist處理二維數據,但它只創建兩個交錯的一維直方圖。 – 2010-01-15 15:58:07

0

使用xlimylim來設置圖的限制。 xlim(-3, 3)ylim(-3, 3)應該這樣做。

2

我意識到有一個補丁提交給matplotlib,但我採用了另一個示例中的代碼來解決我的一些需求。

現在直方圖是從左下角作圖,如在常規的數學(未計算)

也,像素合併範圍以外的值被忽略,並且我使用2D numpy的陣列用於二維陣列的

我改變的數據輸入從對兩個一維數組,因爲這是數據是如何供應到散射(X,Y)和相似的功能

def histBin(x,y,x_range=(0.0,1.0),y_range=(0.0,1.0),xbins=10,ybins=None): 
    """ Helper function to do 2D histogram binning 
     x, y are lists/2D arrays 
     x_range and yrange define the range of the plot similar to the hist(range=...) 
     xbins,ybins are the number of bins within this range. 
    """ 

    pairsData = zip(x,y) 

    if (ybins == None): 
     ybins = xbins 
    xdata, ydata = zip(*pairsData) 
    xmin,xmax = x_range 
    xmin = float(xmin) 
    xmax = float(xmax) 

    xwidth = xmax-xmin 
    ymin,ymax = y_range  
    ymin = float(ymin) 
    ymax = float(ymax) 
    ywidth = ymax-ymin 

    def xbin(xval): 
     return floor(xbins*(xval-xmin)/xwidth) if xmin <= xval < xmax else xbins-1 if xval ==xmax else None 


    def ybin(yval): 
     return floor(ybins*(yval-ymin)/ywidth) if ymin <= yval < ymax else ybins-1 if yval ==ymax else None 

    hist = numpy.zeros((xbins,ybins)) 
    for x,y in pairsData: 
     i_x,i_y = xbin(x),ybin(ymax-y) 
     if i_x is not None and i_y is not None: 
      hist[i_y,i_x] += 1 

    extent = (xmin,xmax,ymin,ymax) 

    return hist,extent