2010-01-08 17 views
19

Tengo una serie de valores (x, y) que quiero trazar un histograma en 2d de usar matplotlib de python. Usando hexbin, me sale algo como esto: alt text http://img121.imageshack.us/img121/1339/hexbin.png Pero yo estoy buscando algo como esto: alt text http://img17.imageshack.us/img17/1927/recthist.png Ejemplo de código:Conteo rectangular de Python Matplotlib

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() 

Parece que ya debería haber una manera de hacer esto sin necesidad de escribir mi propio método "binning" y usando imshow.

Respuesta

12

Numpy tiene una función llamada histogram2d, cuya cadena de documentación también se muestra cómo visualizar usando Matplotlib. Agregue interpolation=nearest a la llamada imshow para deshabilitar la interpolación.

0

es matplotlib.pyplot.hist ¿Qué estás buscando?

>>> 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

este es uno dimensional. Estoy buscando un histograma bidimensional, similar a lo que imshow() o hexbin() – job

+0

* hist * pueden hacer datos 2D, a menos que no entienda su punto. Si publicó algunos datos de ejemplo, eso podría ayudar. – Seth

+2

Hist funciona en datos 2D, pero solo crea dos histogramas 1D intercalados. –

0

Utilice xlim y ylim para establecer los límites de la trama. xlim(-3, 3) y ylim(-3, 3) deberían hacerlo.

2

Me doy cuenta de que hay un parche enviado a matplotlib, pero adopté el código del otro ejemplo para acomodar algunas necesidades que tenía.

ahora el histograma se representa desde la esquina inferior izquierda, como en matemáticas convencional (no Computing)

también, los valores fuera de la gama binning se ignoran y utilizar una matriz numpy 2d para la matriz de dos dimensiones

I cambió la entrada de datos a partir de pares de dos matrices 1D ya que esto es cómo se suministran los datos para dispersar (x, y) y las funciones por igual

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 
Cuestiones relacionadas