Python Matplotlib 矩形分箱

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2030970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:37:09  来源:igfitidea点击:

Python Matplotlib rectangular binning

pythonmatplotlibhistogram

提问by job

I've got a series of (x,y) values that I want to plot a 2d histogram of using python's matplotlib. Using hexbin, I get something like this: alt textBut I'm looking for something like this: alt textExample Code:

我有一系列 (x,y) 值,我想绘制使用 python 的 matplotlib 的二维直方图。使用 hexbin,我得到了这样的东西: 替代文字但我正在寻找这样的东西: 替代文字示例代码:

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

It seems like there should already be a way to do this without writing my own "binning" method and using imshow.

似乎应该已经有一种方法可以在不编写我自己的“分箱”方法和使用 imshow 的情况下做到这一点。

采纳答案by Jouni K. Sepp?nen

Numpy has a function called histogram2d, whose docstring also shows you how to visualize it using Matplotlib. Add interpolation=nearestto the imshow call to disable the interpolation.

Numpy 有一个名为histogram2d的函数,其文档字符串还向您展示了如何使用 Matplotlib 对其进行可视化。添加interpolation=nearest到 imshow 调用以禁用插值。

回答by wirrbel

I realize that there is a patch submitted to matplotlib, but I adopted the code from the other example to acommodate a few needs that I had.

我意识到有一个补丁提交给了 matplotlib,但我采用了另一个示例中的代码来满足我的一些需求。

now the histogram is plotted from the lower left corner, as in conventional math (not computing)

现在直方图是从左下角绘制的,就像在传统数学中一样(不是计算)

also, values outside the binning range are ignored and I use a 2d numpy array for the twodimensional array

此外,binning 范围之外的值将被忽略,我使用二维 numpy 数组作为二维数组

I changed the data input from pairs to two 1D arrays since this is how data is supplied to scatter(x,y) and alike functions

我将数据输入从成对更改为两个一维数组,因为这是向 scatter(x,y) 和类似函数提供数据的方式

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

回答by Piti Ongmongkolkul

I just submitted a pull request for this https://github.com/matplotlib/matplotlib/pull/805. Hopefully, it will be accepted.

我刚刚为此https://github.com/matplotlib/matplotlib/pull/805提交了拉取请求。希望它会被接受。

回答by anonymous

Use xlimand ylimto set the limits of the plot. xlim(-3, 3)and ylim(-3, 3)should do it.

使用xlimylim来设置图的界限。xlim(-3, 3)并且ylim(-3, 3)应该这样做。

回答by Seth

Is matplotlib.pyplot.histwhat you're looking for?

matplotlib.pyplot.hist你要找的吗?

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