根据《科研论文配图绘制指南——基于Python》第三章中直方图的绘制部分,对章节重点进行归纳总结,主要介绍了运用Matplotlib库、proplots库进行直方图的绘制,并介绍了如何利用 Python 绘制上图所示的带统计信息的直方图

直方图的绘制

Matplotlib 中,我们可使用 axes.Axes.hist() 函数绘制直方图。在 axes.Axes.hist() 函数中,参数 x 为要绘制的样本数据;参数 bins 用于定义分布区间,该参数的值可设置成整数、给定数值序列或字符串,默认为数值类型且值为 10。当参数 bins 的值为整数时,定义范围内等宽bin 的数量。当数bins 的值为自定义数值序列时,定义 bin 边缘数值,包括第一个 bin 的左边缘和最后一个 bin 的右边缘。注意,在上述这种情况下,bin 的间距可不相等。当参数 bins 的值为字符串类型时,可选“auto”“fd”“rice”和“sqrt”等值。axes.Axes.hist() 函数的参数 density对应的值为布尔型,该参数决定绘图结果是否为密度图,默认值为 False。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams["ytick.right"] = False
hist_data = pd.read_excel(r"/单变量图形的绘制/柱形图绘制数.xlsx")
hist_x_data = hist_data["hist_data"].values
bins = np.arange(0.0,1.5,0.1)
fig,ax = plt.subplots(figsize = (4,3.5),dpi = 100)
hist = ax.hist(x = hist_x_data, bins = bins,
color = "#3F3F3F", edgecolor = 'black',
rwidth = 0.8)
ax.tick_params(axis = "x",which = "minor",top = False,
bottom = False)
ax.set_xticks(np.arange(0,1.4,0.1))
ax.set_yticks(np.arange(0.,2500,400))
ax.set_xlim(-.05,1.3)
ax.set_ylim(0.0,2500)
ax.set_xlabel('Values', )
ax.set_ylabel('Frequency')
plt.show()

此为柱形直方图示例代码,效果图如下:

python绘制直方图plt并设置每个柱子之间的间隔_正态分布

import proplot as pplt 
from proplot import rc
import numpy as np
import pandas as pd
hist_data = pd.read_excel(r"/单变量图形的绘制/柱形图绘制数.xlsx")
hist_x_data = hist_data["hist_data"].values
bins = np.arange(0.0,1.5,0.1)
rc["axes.labelsize"] = 15
rc['tick.labelsize'] = 12
rc["suptitle.size"] = 15
fig = pplt.figure(figsize=(3.5,3))
ax = fig.subplot()
ax.format(abc = 'a.', abcloc = 'ur', abcsize = 16,
xlabel = 'Values', ylabel = 'Frequency',
xlim = (-.05,1.3), ylim=(0,2500))
hist = ax.hist(x = hist_x_data, bins = bins,
color = "#3F3F3F",
edgecolor = 'black', rwidth = 0.8)

此代码为运用proplot绘制直方图示例代码,效果图如下:

python绘制直方图plt并设置每个柱子之间的间隔_信息可视化_02

有时,为了显示一些必要的统计信息,我们需要在直方图中添加正态分布曲线(normaldistribution curve)、均值线(mean line)和中位数线(median line)等,或者以短竖线样式在 X轴位置处表示数据点。

python绘制直方图plt并设置每个柱子之间的间隔_直方图_03

利用 Python 绘制上图所示的带统计信息的直方图的难点在于正态分布曲线的计算和绘制。上图为 Matplotlib 绘制的添加了正态分布曲线和中位数线的直方图示例。我们可以使用 scipy.stats.norm() 函数对绘制数据实现正态拟合,计算出概率密度函数(Probability Density Function,PDF)结果。由于概率密度函数结果是归一化的,即曲线下方的面积为 1,而直方图的总面积是样本数和每个 bin 宽度的乘积,因此,对概率密度函数结果与样本个数、bin 宽度值相乘的结果进行绘制,即可将绘制的曲线缩放到直方图的高度。

其核心代码如下:

import numpy as np
import pandas as pd
from scipy.stats import norm
import matplotlib.pyplot as plt
hist_data02 = pd.read_csv(r"\单变量图形的绘制\直方图绘制02.csv") 
bins=15
hist_x_data = hist_data02["hist_data"].values
Median = np.median(hist_x_data)
mu,std = norm.fit(hist_x_data)
fig,ax = plt.subplots(figsize=(5,3.5),dpi=100)
hist = ax.hist(x=hist_x_data, bins=bins,color="gray",
edgecolor ='black',lw=.5)
# 绘制正态分布曲线(Plot the PDF)
xmin, xmax = min(hist_x_data),max(hist_x_data)
x = np.linspace(xmin, xmax, 100) # 100为随机选择,值越大,绘制曲线越密集
p = norm.pdf(x, mu, std)
N = len(hist_x_data)
bin_width = (x.max() - x.min()) / bins
ax.plot(x, p*N*bin_width,linewidth=1,color="r",
label="Normal Distribution Curve")
# 添加均值线
ax.axvline(x=Median,ls="--",lw=1.2,color="b",
label="Median Line")
ax.set_xlabel('Values')
ax.set_ylabel('Count')
ax.legend(frameon=False)
plt.show()