如何在直方图中居中标签

时间:2014-04-23 13:37:48

标签: python numpy matplotlib histogram

我有一个看起来像

的numpy数组results
[ 0.  2.  0.  0.  0.  0.  3.  0.  0.  0.  0.  0.  0.  0.  0.  2.  0.  0.
  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.
  0.  1.  1.  0.  0.  0.  0.  2.  0.  3.  1.  0.  0.  2.  2.  0.  0.  0.
  0.  0.  0.  0.  0.  1.  1.  0.  0.  0.  0.  0.  0.  2.  0.  0.  0.  0.
  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  3.  1.  0.  0.  0.  0.  0.
  0.  0.  0.  1.  0.  0.  0.  1.  2.  2.]

我想绘制它的直方图。我试过了

import matplotlib.pyplot as plt
plt.hist(results, bins=range(5))
plt.show()

这给了我一个x轴标记为0.0 0.5 1.0 1.5 2.0 2.5 3.0. 3.5 4.0的直方图。

我希望x轴标记为0 1 2 3而不是每个条形图中心的标签。你怎么能这样做?

6 个答案:

答案 0 :(得分:8)

其他答案就是不要为我做。使用weeks优于plt.bar的好处是该栏可以使用plt.hist

align='center'

centering labels in a histogram

答案 1 :(得分:6)

以下替代解决方案与plt.hist()兼容(例如,您可以在pandas.DataFrame.hist()之后调用它。

import numpy as np

def bins_labels(bins, **kwargs):
    bin_w = (max(bins) - min(bins)) / (len(bins) - 1)
    plt.xticks(np.arange(min(bins)+bin_w/2, max(bins), bin_w), bins, **kwargs)
    plt.xlim(bins[0], bins[-1])

(OP没有严格要求最后一行,但它使输出更好)

这可以用作:

import matplotlib.pyplot as plt
bins = range(5)
plt.hist(results, bins=bins)
bins_labels(bins, fontsize=20)
plt.show()

Result: success!

答案 2 :(得分:5)

您可以使用bar构建np.histogram图。

考虑一下

his = np.histogram(a,bins=range(5))
fig, ax = plt.subplots()
offset = .4
plt.bar(his[1][1:],his[0])
ax.set_xticks(his[1][1:] + offset)
ax.set_xticklabels( ('1', '2', '3', '4') )

enter image description here

编辑:为了使这些条形图相互接触,必须使用width参数。

 fig, ax = plt.subplots()
 offset = .5
 plt.bar(his[1][1:],his[0],width=1)
 ax.set_xticks(his[1][1:] + offset)
 ax.set_xticklabels( ('1', '2', '3', '4') )

enter image description here

答案 3 :(得分:1)

这是仅使用plt.hist()的解决方案。 让我们将其分为两部分:

  1. 将x轴标记为0 1 2 3
  2. 将标签放在每个条形的中心。

要使x轴标记为0 1 2 3而没有.5值,可以使用函数plt.xticks()并在x轴上提供所需的值作为参数。对于您的情况,由于您需要0 1 2 3,因此可以致电plt.xticks(range(4))

要在每个条形的中间放置标签,可以将参数align='left'传递给plt.hist()函数。下面是您的代码,只需对其进行最少的修改即可。

import numpy as np
import matplotlib.pyplot as plt

results = [0,  2,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,
           0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,
           0,  1,  1,  0,  0,  0,  0,  2,  0,  3,  1,  0,  0,  2,  2,  0,  0,  0,
           0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,
           0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  1,  0,  0,  0,  0,  0,
           0,  0,  0,  1,  0,  0,  0,  1,  2,  2]

plt.hist(results, bins=range(5), align='left')
plt.xticks(range(4))
plt.show()

enter image description here

答案 4 :(得分:0)

就像Jarad在回答中指出的那样,barplot是一种精巧的方法。这是使用熊猫绘制Barplot的一种简短方法。

import pandas as pd
import matplotlib.pyplot as plt

arr = [ 0.,  2.,  0.,  0.,  0.,  0.,  3.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  2.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,
        0.,  0.,  0.,  0.,  2.,  0.,  3.,  1.,  0.,  0.,  2.,  2.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  0.,  0.,  0.,
        0.,  0.,  2.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  3.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  1.,  0.,  0.,  0.,  1.,  2.,  2.]

col = 'name'
pd.DataFrame({col : arr}).groupby(col).size().plot.bar()
plt.show()

答案 5 :(得分:0)

将标签居中放在离散值的 matplotlib 直方图上就足以将“bins”定义为 bin 边界列表。

import matplotlib.pyplot as plt
%matplotlib inline

example_data = [0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1]

fig = plt.figure(figsize=(5,5))
ax1 = fig.add_subplot()
ax1_bars = [0,1]                           
ax1.hist( 
    example_data, 
    bins=[x for i in ax1_bars for x in (i-0.4,i+0.4)], 
    color='#404080')
ax1.set_xticks(ax1_bars)
ax1.set_xticklabels(['class 0 label','class 1 label'])
ax1.set_title("Example histogram")
ax1.set_yscale('log')
ax1.set_ylabel('quantity')

fig.tight_layout()
plt.show()

enter image description here

这是如何工作的?

  • 直方图 bins 参数可以是定义 bin 边界的列表。对于可以假定值为 0 或 1 的类,这些边界应该是 {{ 1}} 粗略地翻译为“bin 0”是从 -0.5 到 1.5,而“bin 1”是从 0.5 到 1.5。由于这些范围的中间是离散值,因此标签将位于预期位置。

  • 表达式 [ -0.5, 0.5, 0.5, 1.5 ] 只是为值列表 ([x for i in ax_bars for x in (i-0.4,i+0.4)]) 生成边界列表的一种方式。

  • 表达式 ax_bars 对于将 x 轴设置为离散的很重要。

  • 其余的应该是不言自明的。