2010-01-08 14 views
19

Mam szereg wartości (x, y), które chcę wykreślić histogram 2d przy użyciu matplotlib Pythona. Korzystanie hexbin, mam coś takiego: alt text http://img121.imageshack.us/img121/1339/hexbin.png Ale szukam czegoś takiego: alt text http://img17.imageshack.us/img17/1927/recthist.png przykładowy kod:Python Matplotlib prostokątne 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() 

Wydaje się, że nie powinno być już sposób to zrobić bez pisania mój własną metodę "binning" i używanie imshow.

Odpowiedz

12

Numpy posiada funkcję o nazwie histogram2d, którego docstring także pokazuje, jak wizualizować go przy użyciu matplotlib. Dodaj interpolation=nearest do wywołania imshow, aby wyłączyć interpolację.

0

Czy jest to matplotlib.pyplot.hist czego szukasz?

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

to jest jednowymiarowe. Szukam dwuwymiarowego histogramu, podobnego do tego, co imshow() lub hexbin() – job

+0

* hist * może wykonywać dane 2D, chyba że nie rozumiem. Jeśli zamieściłeś przykładowe dane, może to pomóc. – Seth

+2

Hist działa na danych 2D, ale tworzy tylko dwa przeplecione histogramy 1D. –

0

Użyj xlim i ylim, aby ustawić granice wykresu. xlim(-3, 3) i ylim(-3, 3) powinny to zrobić.

2

Zdaję sobie sprawę, że istnieje łatka zgłoszona do matplotlib, ale przyjąłem kod z drugiego przykładu, aby zaspokoić kilka potrzeb, które miałem.

się histogram jest przedstawiony od dolnego lewego rogu, tak jak w konwencjonalnym matematyce (nie komputerowych)

również wartości spoza zakresu binningu są ignorowane i używać 2d numpy tablicę dla dwuwymiarowego tablicy

Zmieniłem wprowadzanie danych z parami do dwóch 1D tablic, gdyż jest to w jaki sposób dane są dostarczane do rozproszenia (x, y) i podobne funkcje

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 
Powiązane problemy