【2.2】柱形图(matplotlib-hist)

一、概念

区分直方图与条形图:

  • 条形图是用条形的长度表示各类别频数的多少,其宽度(表示类别)则是固定的;
  • 直方图是用面积表示各组频数的多少,矩形的高度表示每一组的频数或频率,宽度则表示各组的组距,因此其高度与宽度均有意义。
  • 由于分组数据具有连续性,直方图的各矩形通常是连续排列,而条形图则是分开排列。
  • 条形图主要用于展示分类数据,而直方图则主要用于展示数据型数据

更多参数说明

  • color:可以是一个list,用于对应每个bin的颜色
  • range: 选择保留的数字范围

二、常见的例子

2.1 常规例子

from numpy.random import normal
gaussian_numbers = normal(size=1000)
import matplotlib.pyplot as plt
from numpy.random import normal
gaussian_numbers = normal(size=1000)
plt.hist(gaussian_numbers)
plt.title("Gaussian Histogram")
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.show()

因为histogram默认是生成10个bin,有时候我们觉得区分细度不够的时候,可以人为来增加bin

plt.hist(gaussian_numbers, bins=20)
plt.show()

我们也可以将纵坐标的频数转换成频率

plt.hist(gaussian_numbers, bins=20, normed=True)
plt.show()

2.2 作累积概率分布图(cumulative distribution)

plt.hist(gaussian_numbers, bins=20, normed=True, cumulative=True)
plt.show()

2.3 指定bin的横坐标范围

plt.hist(gaussian_numbers, bins=(-10,-1,1,10))
plt.show()

2.4 未填充的bar

plt.hist(gaussian_numbers, bins=20, histtype='step')
plt.show()

histtype

{‘bar’, ‘barstacked’, ‘step’, ‘stepfilled’}, optional The type of histogram to draw.

‘bar’ is a traditional bar-type histogram. If multiple data are given the bars are arranged side by side. ‘barstacked’ is a bar-type histogram where multiple data are stacked on top of each other. ‘step’ generates a lineplot that is by default unfilled. ‘stepfilled’ generates a lineplot that is by default filled. Default is ‘bar’

三、更高级的用法

3.1 两个hist图的重叠

例1

import matplotlib.pyplot as plt
from numpy.random import normal, uniform
gaussian_numbers = normal(size=1000)
uniform_numbers = uniform(low=-3, high=3, size=1000)
plt.hist(gaussian_numbers, bins=20, histtype='stepfilled', normed=True, color='b', label='Gaussian')
plt.hist(uniform_numbers, bins=20, histtype='stepfilled', normed=True, color='r', alpha=0.5, label='Uniform')
plt.title("Gaussian/Uniform Histogram")
plt.xlabel("Value")
plt.ylabel("Probability")
plt.legend()
plt.show()

例2:

import random
import numpy
from matplotlib import pyplot

x = [random.gauss(3,1) for _ in range(400)]
y = [random.gauss(4,2) for _ in range(400)]

bins = numpy.linspace(-10, 10, 100)

pyplot.hist(x, bins, alpha=0.5, label='x')
pyplot.hist(y, bins, alpha=0.5, label='y')
pyplot.legend(loc='upper right')
pyplot.show()

例3

import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-deep')

x = np.random.normal(1, 2, 5000)
y = np.random.normal(-1, 3, 2000)
bins = np.linspace(-10, 10, 30)

plt.hist([x, y], bins, label=['x', 'y'])
plt.legend(loc='upper right')
plt.show()

3.2 x、y轴互换

import numpy as np
import matplotlib.pyplot as plt

data = np.random.exponential(1, 100)

# Showing the first plot.
plt.hist(data, bins=10)
plt.show()

# Cleaning the plot (useful if you want to draw new shapes without closing the figure
# but quite useless for this particular example. I put it here as an example).
plt.gcf().clear()

# Showing the plot with horizontal orientation
plt.hist(data, bins=10, orientation='horizontal')
plt.show()

# Cleaning the plot.
plt.gcf().clear()

# Showing the third plot with orizontal orientation and inverted y axis.
plt.hist(data, bins=10, orientation='horizontal')
plt.gca().invert_yaxis()
plt.show()

图1:

图2:

图3:

3.3 y轴log化

plt.hist(** ,log =True)

3.4 加叠合曲线

# -*- coding:utf-8 -*-
import pandas as pd
import numpy as np
import random


data = np.zeros((1000,1000),dtype=int)
for i in range(len(data)):#这里速度比较慢,因为随机给1000*1000的数组赋值
    for j in range(len(data[0])):
        data[i][j] = random.randint(1,20)#赋值的范围是1-20中的任意一个

#首先构造数据,这里注意构造的是一维数组可以使用pandas中的Series,如果是二维数组使用DataFrame。
data_m = pd.DataFrame(data)
data_m = data_m[1].value_counts()#注意value_counts函数统计一个series上的数据情况
data_m = data_m.sort_index()#给统计后的数据排序
print(data_m)

#随后开始画直方图
import matplotlib.pyplot as plt
plt.hist(data[0])
plt.show()

plt.hist(data[0],bins=20)
plt.show()

四、讨论

4.1 bins 没有在ticks对应的正中心

需要被讨论的例子:

import matplotlib.pyplot as plt
l = [3,3,3,2,1,4,4,5,5,5,5,5,5,5,5,5]
plt.hist(l,normed=True)
plt.show()

解决问题的方法

import matplotlib.pyplot as plt
aa = [3,3,3,2,1,4,4,5,5,5,5,5,5,5,5,5]
plt.hist(aa,normed=False,bins=range(0,7),rwidth = 0.5,align='left')
plt.xticks(range(7),range(7))
# plt.yticks(range(6),range(6))
plt.show()

  • bins 可以接受两种类型的参数,如果是数字,则代表bin的数量;如果是一个区间,则 代表在什么位置切割成一个个的bin ,举个例子吧,bins=range(1,7),则代表形成[1,2], [2,3], [3,4], …, [5, 6]区间,每个区间的取值为一个bin
  • align : bin对齐的位置,默认是middle ,这里需要改成left
  • rwidth: bin的宽度
  • normed=True的时候,不要随意rwidth,否则比例会不对

五、报错

报错1

ValueError: range parameter must be finite.

解决办法:

当在使用hist() 或者histogram() 遇到上述错误,多数是数据中存在NaN,使用fillna()等转化NaN 为其他numeric即可

参考资料

个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn

Sam avatar
About Sam
专注生物信息 专注转化医学