2010-01-08 4 views
19

У меня есть ряд значений (x, y), которые я хочу построить 2d-гистограмму использования matplotlib на python. Используя hexbin, я получаю что-то вроде этого: alt text http://img121.imageshack.us/img121/1339/hexbin.png Но я искал что-то вроде этого: alt text http://img17.imageshack.us/img17/1927/recthist.png Пример кода:Python Matplotlib rectangular 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() 

Похоже, там уже должен быть способ сделать это без написания моего собственный метод «binning» и использование 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

+0

* hist * может делать 2D-данные, если только я не получу вашу точку. Если вы разместили некоторые данные примера, это может помочь. – Seth

+2

Hist работает над двумерными данными, но он просто создает две чередующиеся 1D гистограммы. –

0

Используйте xlim и ylim, чтобы установить пределы участка. xlim(-3, 3) и ylim(-3, 3) должны это сделать.

2

Я понимаю, что есть патч, представленный matplotlib, но я принял код из другого примера, чтобы удовлетворить некоторые потребности, которые у меня были.

теперь гистограмма построена из нижнего левого угла, как и в обычной математике (не вычисления)

также значения вне диапазона биннинга игнорируются и я использую 2d Numpy массив для двумерного массива

Я изменил данные, вводимый из двух пар 1D массивов, так это то, как данные поступают разбрасывать (х, у) и функция подобно

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