将 matplotlib 直方图除以最大 bin 值
Dividing matplotlib histogram by maximum bin value
我想在同一个图上绘制多个直方图,我需要比较数据的分布。我想通过将每个直方图除以它的最大值来做到这一点,这样所有的分布都具有相同的比例。然而,matplotlib 的直方图函数的工作方式,我还没有找到一个简单的方法来做到这一点。
这是因为n在
n, bins, patches = ax1.hist(y, bins = 20, histtype = 'step', color = 'k')
是每个 bin 中的计数,但我无法将其重新传递给 hist,因为它会重新计算。
我尝试了范数和密度函数,但这些函数对分布的面积进行了归一化,而不是对分布的高度进行了归一化。我可以复制 n,然后使用 bins 输出重复 bin 边缘,但这很乏味。当然 hist 函数必须允许 bins 值除以一个常数?
示例代码如下,演示了问题。
y1 = np.random.randn(100)
y2 = 2*np.random.randn(50)
x1 = np.linspace(1,101,100)
x2 = np.linspace(1,51,50)
gs = plt.GridSpec(1,2, wspace = 0, width_ratios = [3,1])
ax = plt.subplot(gs[0])
ax1 = plt.subplot(gs[1])
ax1.yaxis.set_ticklabels([]) # remove the major ticks
ax.scatter(x1, y1, marker='+',color = 'k')#, c=SNR, cmap=plt.cm.Greys)
ax.scatter(x2, y2, marker='o',color = 'k')#, c=SNR, cmap=plt.cm.Greys)
n1, bins1, patches1 = ax1.hist(y1, bins = 20, histtype = 'step', color = 'k',linewidth = 2, orientation = 'horizontal')
n2, bins2, patched2 = ax1.hist(y2, bins = 20, histtype = 'step', linestyle = 'dashed', color = 'k', orientation = 'horizontal')
您可以将参数 bins
赋给一个值列表。使用 np.arange()
或 np.linspace()
生成值。 http://matplotlib.org/api/axes_api.html?highlight=hist#matplotlib.axes.Axes.hist
我不知道 matplotlib 是否默认允许这种规范化,但我自己写了一个函数来做。
它从 plt.hist(如上)获取 n
和 bins
的输出,然后将其传递给下面的函数。
def hist_norm_height(n,bins,const):
''' Function to normalise bin height by a constant.
Needs n and bins from np.histogram or ax.hist.'''
n = np.repeat(n,2)
n = float32(n) / const
new_bins = [bins[0]]
new_bins.extend(np.repeat(bins[1:],2))
return n,new_bins[:-1]
现在绘制(我喜欢阶梯直方图),你将它传递给 plt.step。
如plt.step(new_bins,n)
。这将为您提供一个高度由常数归一化的直方图。
为进行比较而设置的方法略有不同。可适配步进样式:
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
y = []
y.append(np.random.normal(2, 2, size=40))
y.append(np.random.normal(3, 1.5, size=40))
y.append(np.random.normal(4,4,size=40))
ls = ['dashed','dotted','solid']
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3)
for l, data in zip(ls, y):
n, b, p = ax1.hist(data, normed=False,
#histtype='step', #step's too much of a pain to get the bins
#color='k', linestyle=l,
alpha=0.2
)
ax2.hist(data, normed=True,
#histtype = 'step', color='k', linestyle=l,
alpha=0.2
)
n, b, p = ax3.hist(data, normed=False,
#histtype='step', #step's too much of a pain to get the bins
#color='k', linestyle=l,
alpha=0.2
)
high = float(max([r.get_height() for r in p]))
for r in p:
r.set_height(r.get_height()/high)
ax3.add_patch(r)
ax3.set_ylim(0,1)
ax1.set_title('hist')
ax2.set_title('area==1')
ax3.set_title('fix height')
plt.show()
几个输出:
这可以通过使用 numpy
获得先验直方图值,然后使用 bar plot 绘制它们来完成。
import numpy as np
import matplotlib.pyplot as plt
# Define random data and number of bins to use
x = np.random.randn(1000)
bins = 10
plt.figure()
# Obtain the bin values and edges using numpy
hist, bin_edges = np.histogram(x, bins=bins, density=True)
# Plot bars with the proper positioning, height, and width.
plt.bar(
(bin_edges[1:] + bin_edges[:-1]) * .5, hist / hist.max(),
width=(bin_edges[1] - bin_edges[0]), color="blue")
plt.show()
我想在同一个图上绘制多个直方图,我需要比较数据的分布。我想通过将每个直方图除以它的最大值来做到这一点,这样所有的分布都具有相同的比例。然而,matplotlib 的直方图函数的工作方式,我还没有找到一个简单的方法来做到这一点。
这是因为n在
n, bins, patches = ax1.hist(y, bins = 20, histtype = 'step', color = 'k')
是每个 bin 中的计数,但我无法将其重新传递给 hist,因为它会重新计算。
我尝试了范数和密度函数,但这些函数对分布的面积进行了归一化,而不是对分布的高度进行了归一化。我可以复制 n,然后使用 bins 输出重复 bin 边缘,但这很乏味。当然 hist 函数必须允许 bins 值除以一个常数?
示例代码如下,演示了问题。
y1 = np.random.randn(100)
y2 = 2*np.random.randn(50)
x1 = np.linspace(1,101,100)
x2 = np.linspace(1,51,50)
gs = plt.GridSpec(1,2, wspace = 0, width_ratios = [3,1])
ax = plt.subplot(gs[0])
ax1 = plt.subplot(gs[1])
ax1.yaxis.set_ticklabels([]) # remove the major ticks
ax.scatter(x1, y1, marker='+',color = 'k')#, c=SNR, cmap=plt.cm.Greys)
ax.scatter(x2, y2, marker='o',color = 'k')#, c=SNR, cmap=plt.cm.Greys)
n1, bins1, patches1 = ax1.hist(y1, bins = 20, histtype = 'step', color = 'k',linewidth = 2, orientation = 'horizontal')
n2, bins2, patched2 = ax1.hist(y2, bins = 20, histtype = 'step', linestyle = 'dashed', color = 'k', orientation = 'horizontal')
您可以将参数 bins
赋给一个值列表。使用 np.arange()
或 np.linspace()
生成值。 http://matplotlib.org/api/axes_api.html?highlight=hist#matplotlib.axes.Axes.hist
我不知道 matplotlib 是否默认允许这种规范化,但我自己写了一个函数来做。
它从 plt.hist(如上)获取 n
和 bins
的输出,然后将其传递给下面的函数。
def hist_norm_height(n,bins,const):
''' Function to normalise bin height by a constant.
Needs n and bins from np.histogram or ax.hist.'''
n = np.repeat(n,2)
n = float32(n) / const
new_bins = [bins[0]]
new_bins.extend(np.repeat(bins[1:],2))
return n,new_bins[:-1]
现在绘制(我喜欢阶梯直方图),你将它传递给 plt.step。
如plt.step(new_bins,n)
。这将为您提供一个高度由常数归一化的直方图。
为进行比较而设置的方法略有不同。可适配步进样式:
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
y = []
y.append(np.random.normal(2, 2, size=40))
y.append(np.random.normal(3, 1.5, size=40))
y.append(np.random.normal(4,4,size=40))
ls = ['dashed','dotted','solid']
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3)
for l, data in zip(ls, y):
n, b, p = ax1.hist(data, normed=False,
#histtype='step', #step's too much of a pain to get the bins
#color='k', linestyle=l,
alpha=0.2
)
ax2.hist(data, normed=True,
#histtype = 'step', color='k', linestyle=l,
alpha=0.2
)
n, b, p = ax3.hist(data, normed=False,
#histtype='step', #step's too much of a pain to get the bins
#color='k', linestyle=l,
alpha=0.2
)
high = float(max([r.get_height() for r in p]))
for r in p:
r.set_height(r.get_height()/high)
ax3.add_patch(r)
ax3.set_ylim(0,1)
ax1.set_title('hist')
ax2.set_title('area==1')
ax3.set_title('fix height')
plt.show()
几个输出:
这可以通过使用 numpy
获得先验直方图值,然后使用 bar plot 绘制它们来完成。
import numpy as np
import matplotlib.pyplot as plt
# Define random data and number of bins to use
x = np.random.randn(1000)
bins = 10
plt.figure()
# Obtain the bin values and edges using numpy
hist, bin_edges = np.histogram(x, bins=bins, density=True)
# Plot bars with the proper positioning, height, and width.
plt.bar(
(bin_edges[1:] + bin_edges[:-1]) * .5, hist / hist.max(),
width=(bin_edges[1] - bin_edges[0]), color="blue")
plt.show()