matplotlib绘图优化-使用np.histogram绘制直方图(柱状图)

  • A+
所属分类:python数据分析
摘要这一篇介绍了绘制直方图的方式,我们使用np.histogram与plt.bar的方式完成了与plt.hist同样的效果,同时绘制了多个直方图与堆叠直方图(柱状图).

简介

这里会介绍绘制直方图的一些方式。其实绘制直方图可以使用plt.hist来进行绘制,参考连接 : Python数据处理之Matplotlib学习--直方图绘制。但是直方图的绘制有个问题(主要是我对直方图的操作不是很熟练),所以画一些好看的图比较麻烦。

于是这里我们会使用numpy.histogram来先完成直方图的统计,在使用柱状图来进行绘制。

numpy.histogram的介绍

这里我们简单介绍一下numpy.histogram的使用,看一下他的输入和输出。下面是一个简单的例子。

  1. # 生成一些随机数
  2. rng = np.random.RandomState(10)
  3. data1 = rng.normal(size=1000)
  4. data2 = rng.normal(size=1000)
  5. # 查看np.histogram的输出
  6. binRange = np.arange(-1,1,0.1)
  7. print(binRange)
  8. np.histogram(data1, bins=binRange)

关于np.histogram的输入,data1表示需要统计的数据, binRange是按照这里的区间进行统计。在这里binRange生成如下,表示从-1到1, 每隔0.1取一个。np.histogram就会统计各个区间的个数,如data1在[-1, -0.9)之间样本的个数。

  1. [-1.00000000e+00 -9.00000000e-01 -8.00000000e-01 -7.00000000e-01
  2.  -6.00000000e-01 -5.00000000e-01 -4.00000000e-01 -3.00000000e-01
  3.  -2.00000000e-01 -1.00000000e-01 -2.22044605e-16  1.00000000e-01
  4.   2.00000000e-01  3.00000000e-01  4.00000000e-01  5.00000000e-01
  5.   6.00000000e-01  7.00000000e-01  8.00000000e-01  9.00000000e-01]

我们简单看一下np.histogram的输出。他的输出有两个部分:

  • 第一个部分表示每个区间的统计个数;
  • 第二个部分表示每个区间的边界;
matplotlib绘图优化-使用np.histogram绘制直方图(柱状图)

显示百分比

有的时候, 我们可以显示占比而不是具体的个数, 我们可以使用density=True这个参数来进行设置. 需要注意的是, 在使用density=True的时候, 最后计算出来的结果不一定是1, 而是要和区间的大小进行加权之后是1. 我们看下面的一个例子.

  1. rng=np.random.RandomState(10)
  2. data1=rng.normal(size=1000)
  3. bin_range=[-1,0,2] # 设置区间, 分别是[-1,0]和[0,2]
  4. # 计算每一个区间所占的百分比
  5. hist,_ = np.histogram(data1, bin_range, density=True)
  6. hist
  7. """
  8. array([0.42822678, 0.28588661])
  9. """

可以看到这里计算出的百分比的和不是1, 这个百分比需要和区间大小进行考虑. 我们分别使用区间大小乘以每一个范围所占的比分比, 结果就是1了.

  1. np.sum(hist*np.array([1,2]))
  2. """
  3. 1.0
  4. """

 

np.histogram结合plt.bar绘制直方图

这一部分我们简单介绍一下使用bar来达到hist一样的效果。

绘制多个直方图

首先介绍绘制多个直方图在同一张图中。我们可以看一下下面的例子。就是先用np.histogram统计出每一个区间内data的分布,接着使用plt.bar进行绘制即可。

注意直方图的位置需要通过第一个参数x-w(这个算出的是柱中间的坐标,左右各0.5*w)和width来进行调节。

  1. hist1,_ = np.histogram(data1, bins=binRange)
  2. hist2,_ = np.histogram(data2, bins=binRange)
  3. # 绘制图像
  4. fig, ax1 = plt.subplots()
  5. fig.set_size_inches(10, 6)
  6. plt.set_cmap('RdBu')
  7. x = np.arange(len(binRange)-1)*3
  8. w=0.3
  9. # 绘制多个bar在同一个图中, 这里需要控制width
  10. plt.bar(x-w, hist1, width = 2*w, align='center')
  11. plt.bar(x+w, hist2, width = 2*w, align='center')
  12. # 设置坐标轴的标签
  13. ax1.yaxis.set_tick_params(labelsize=15) # 设置y轴的字体的大小
  14. ax1.set_xticks(x) # 设置xticks出现的位置
  15. # 设置坐标轴名称
  16. ax1.set_ylabel("Count", fontsize='xx-large')
  17. # 设置标题
  18. ax1.set_title('The Distribution of Normal1 Data and Normal2 Data', fontsize='x-large')
  19. # 设置图例
  20. plt.legend(('Normal1','Nomral2'),fontsize = 'x-large', loc='upper right')
  21. plt.show()

最终的绘制的效果如下图所示:

matplotlib绘图优化-使用np.histogram绘制直方图(柱状图)

绘制堆叠直方图

对于有两类的数据,我们除了上面这样两个绘制在一起,我们还可以绘制为堆叠的样式,下面简单看一下例子。

这一部分的使用基本是和上面是一样的,唯一的不同就是第二个需要加上bottom=hist1,也就是在hist1上面绘制hist2的内容。

  1. hist1,_ = np.histogram(data1, bins=binRange)
  2. hist2,_ = np.histogram(data2, bins=binRange)
  3. # 绘制图像
  4. fig, ax1 = plt.subplots()
  5. fig.set_size_inches(10, 6)
  6. plt.set_cmap('RdBu')
  7. x = np.arange(len(binRange)-1)*3
  8. w=1
  9. # 绘制多个bar在同一个图中, 这里需要控制width
  10. plt.bar(x, hist1, width = 2*w, align='center')
  11. plt.bar(x, hist2, width = 2*w, align='center', bottom=hist1)
  12. # 设置坐标轴的标签
  13. ax1.yaxis.set_tick_params(labelsize=15) # 设置y轴的字体的大小
  14. ax1.set_xticks(x) # 设置xticks出现的位置
  15. # 设置坐标轴名称
  16. ax1.set_ylabel("Count", fontsize='xx-large')
  17. # 设置标题
  18. ax1.set_title('The Distribution of Normal1 Data and Normal2 Data', fontsize='x-large')
  19. # 设置图例
  20. plt.legend(('Normal1','Nomral2'),fontsize = 'x-large', loc='upper right')
  21. plt.show()

最终绘制的结果如下图所示:

matplotlib绘图优化-使用np.histogram绘制直方图(柱状图)
  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: