Agrupación rectangular de Python Matplotlib
-
19-09-2019 - |
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:Pero estoy buscando algo como esto:Có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.
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.