Domanda

Ho una serie di valori (x, y) che voglio tracciare un istogramma 2D di utilizzare matplotlib di pitone. Utilizzando hexbin, ho qualcosa di simile: alt text Ma sto cercando qualcosa di simile: alt text Esempio di codice:

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

Sembra che ci dovrebbe già essere un modo per farlo senza scrivere il mio metodo "categorizzazione" e usando imshow.

È stato utile?

Soluzione

Numpy ha una funzione chiamata histogram2d , la cui docstring mostra anche come visualizzare utilizzando Matplotlib. Aggiungere interpolation=nearest alla chiamata imshow per disabilitare l'interpolazione.

Altri suggerimenti

Mi rendo conto che c'è una patch presentato al matplotlib, ma ho adottato il codice dall'altro esempio potevano ospitare alcune esigenze che ho avuto.

Ora l'istogramma viene tracciato dal basso a sinistra, come in matematica convenzionale (non di calcolo)

Inoltre, i valori al di fuori del campo di binning vengono ignorati e io uso un allineamento numpy 2d per l'array bidimensionale

Ho cambiato l'immissione dei dati da coppie di due array 1D poiché questo è come i dati vengono forniti a disperdere (x, y) e funzioni simili

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

Ho appena presentato una richiesta di pull per questo https://github.com/matplotlib/matplotlib/ tirare / 805 . Si spera, sarà accettata.

È matplotlib.pyplot.hist quello che stai cercando?

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

Usa xlim e ylim per impostare i limiti della trama. xlim(-3, 3) e ylim(-3, 3) dovrebbe farlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top