Pregunta

Tengo una serie de valores (x, y) de los que quiero trazar un histograma 2D usando matplotlib de Python.Usando hexbin, obtengo algo como esto:alt textPero estoy buscando algo como esto:alt textCódigo de ejemplo:

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 escribir mi propio método de "binning" y usar imshow.

¿Fue útil?

Solución

Numpy tiene una función llamada histogram2d , cuya docstring también muestra cómo visualizar usando Matplotlib. Añadir interpolation=nearest a la llamada imshow desactivar la interpolación.

Otros consejos

Me doy cuenta de que hay un parche presentado a matplotlib, pero adopté el código desde el otro ejemplo para acommodate unas pocas necesidades que tenía.

ahora el histograma se traza 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

he cambiado la entrada de datos a partir de pares de dos matrices 1D ya que esto es cómo se suministra 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

Yo sólo presenté una solicitud de extracción para este https://github.com/matplotlib/matplotlib/ tire / 805 . Con suerte, será aceptado.

Es matplotlib.pyplot.hist lo que 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.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top