科学数据可视化:Python直方图绘制指南!

学术   2024-06-10 09:30   日本  

直方图(Histogram)是一种统计图表,用于显示数据分布的形态。它通过一系列紧密排列的矩形条形图展示数据在各个区间的频率。每个条形的高度表示该区间的数据点数或频率。

直方图的构成

  1. 横轴(X轴):

  • 表示数据的范围,被划分为若干个区间(bins)。每个区间的宽度相等。

  • 区间的个数和宽度可以根据数据特点和分析目的调整。

  • 纵轴(Y轴):

    • 表示数据在各个区间中的频数或频率。

    • 条形图的高度代表该区间包含的数据点数量。

    直方图的绘制

    直方图基本绘制

    在本案例中,我们将使用Python和常用的可视化库来分析和可视化基因表达数据。首先,我们需要安装并导入必要的Python库。确保你已经安装了以下库:Pandas, Matplotlib, 和 Seaborn。

    # 安装必要的库 
    pip install pandas matplotlib seaborn


    我们使用一个示例基因表达数据集。假设这个数据集名为 gene_expression.xlsx,包含三种不同组织(肝脏、肾脏、心脏)的某个基因的表达水平,每个组织包含150个样本数据。我们以肝脏的基因表达水平为例绘制直方图。

    在绘制直方图时,matplotlib 库的 plt.hist 函数非常强大,提供了许多参数来定制图表的外观和行为。这里我们只介绍常用的参数,其中参数 x 指定要绘制直方图的数据。参数 bins 用于定义分箱的数量或边界,类型可以是整数、序列或字符串(如'auto'),默认为整数10。参数 density 类型为布尔值,如果为 True,则绘制概率密度直方图(总面积为1),默认为 False。参数 cumulative 类型为布尔值,如果为 True,则绘制累积直方图,默认为False。参数 histtype用于指定直方图类型,可以是 'bar''barstacked''step' 或 'stepfilled',默认为 'bar'。参数 orientation 用于指定直方图的方向,可以是 'horizontal' 或 'vertical',默认为 'vertical'。参数 log 类型为布尔值,如果为 True,则使用对数刻度,默认为 False。参数color可指定条形的颜色。参数 label 可指定图例标签。参数 data 可以用于传递数据对象(例如字典或pandas DataFrame),便于使用列名。下图为使用不同参数绘制的直方图实例。

     不同参数绘制的直方图实例


    可见使用不同的参数可绘制样式不同的直方图,图 a 的绘图代码如下所示:

    import os  
    import pandas as pd
    import matplotlib.pyplot as plt

    # 从 Excel 文件中读取数据,确保路径和文件名正确
    df = pd.read_excel('gene_expression.xlsx', sheet_name='GeneExpression')

    # 设置字体和图形参数
    plt.rcParams["font.family"] = "Arial"
    plt.rcParams["axes.linewidth"] = 1
    plt.rcParams["axes.labelsize"] = 14
    plt.rcParams["xtick.labelsize"] = 12
    plt.rcParams["ytick.labelsize"] = 12

    # 绘制直方图
    plt.figure(figsize=(6, 4))
    plt.hist(df['Liver'], bins=10, color='blue', alpha=0.3)

    # 设置坐标轴标签
    plt.xlabel('Expression Level (RNA copies)')
    plt.ylabel('Frequency')

    # 调整图像布局,确保所有元素居中
    plt.tight_layout()

    # 确保保存路径存在
    output_dir = '图像实例/第四章 生物医药领域的专业绘图'
    if not os.path.exists(output_dir):
    os.makedirs(output_dir)

    # 保存图像
    plt.savefig(os.path.join(output_dir, '图4-1-1 直方图绘制实例_a.png'), dpi=600)

    # 显示图像
    plt.show()


    图 b 的绘图核心代码如下所示:

    # 绘制直方图,直方图类型为步骤图(‘step’),绘制累计直方图(cumulative=True)  
    plt.figure(figsize=(6, 4))
    plt.hist(df['Liver'], bins=10, color='blue', alpha=0.3, histtype='step', cumulative=True)


    图 c 的绘图代码如下所示:

    # 绘制直方图,直方图类型为步骤图(‘step’),绘制概率密度直方图(density=True) 
    plt.figure(figsize=(6, 4))
    plt.hist(df['Liver'], bins=30, color='blue', alpha=0.3, density=True)


    带有统计信息的直方图

    在直方图中增加统计信息可以帮助更好地理解数据的分布和特征。常见的统计信息包括:

    1. 平均值 (Mean):数据的算术平均值。

    2. 中位数 (Median):数据的中位数,表示数据的中心位置。

    3. 标准差 (Standard Deviation):衡量数据分布的离散程度。

    4. 最小值和最大值 (Min and Max Values):数据的范围。

    5. 四分位数范围 (Interquartile Range, IQR):衡量数据集中趋势的范围,通常包括25%分位数和75%分位数。

    6. 样本数量(Number, N): 表示数据集中包含的样本个数。

    下图除了绘制直方图外,还添加了相关的统计信息,平均值以红色虚线表示,并标注在图中国;中位数以绿色虚线表示,并标注在图中;标准差、最小值、最大值、四分位数范围 (IQR)信息和样本数量显示在图的左侧。此外,还在直方图上绘制了正态分布曲线。

    带统计信息直方图绘制实例


    在python中可以很容易的实现统计信息的计算,在本例中,我们使用 numpy 库的 mean() 和 median() 函数计算数据的均值和中位数;使用 numpy 库的 std() 函数计算数据的标准差;使用 numpy 库的 min() 和 max() 函数计算数据的最小值和最大值;使用 numpy 库的 percentile() 函数计算数据的第 25 和第 75 百分位数,并计算它们的差值;使用 len() 函数计算数据集中的样本数量。关于正态分布曲线,我们使用 scipy.stats 模块的 norm.pdf() 函数计算给定均值和标准差的正态分布曲线上各点的概率密度值,为了使正态分布曲线与直方图匹配,我们需要将其高度按比例缩放。通过将正态分布曲线的最大高度缩放到直方图的最大柱高,使它们更好地对齐。绘图核心代码如下所示:

    from scipy.stats import norm  

    # 计算统计信息
    mean = np.mean(liver_data) # 计算均值
    median = np.median(liver_data) # 计算中位数
    std_dev = np.std(liver_data) # 计算标准差
    min_val = np.min(liver_data) # 计算最小值
    max_val = np.max(liver_data) # 计算最大值
    iqr = np.percentile(liver_data, 75) - np.percentile(liver_data, 25)
    n = len(liver_data) # 计算数据个数

    # 添加统计信息
    plt.axvline(mean, color='r', linestyle='dashed', linewidth=1, label='Mean line') # 添加均值虚线
    plt.axvline(median, color='g', linestyle='dashed', linewidth=1, label='Median line') # 添加中位数虚线
    # 添加标签,向右移动一定的距离(例如,1 个单位)
    plt.text(mean + 1, plt.ylim()[1]*0.9, f'Mean: {mean:.2f}', color='r')
    # 在均值线旁边添加文本标签
    plt.text(median + 1, plt.ylim()[1]*0.8, f'Median: {median:.2f}', color='g') # 在中位数线旁边添加文本标签

    # 绘制正态分布曲线
    xmin, xmax = plt.xlim() # 获取 x 轴范围
    x = np.linspace(xmin, xmax, 100) # 生成 x 轴上的点
    p = norm.pdf(x, mean, std_dev) # 计算正态分布的 y 值
    # 调整正态分布曲线的比例,使其与直方图匹配
    scale_factor = max(counts) / max(p)
    plt.plot(x, p * scale_factor, 'k', linewidth=1, label='Normal distribution') # 绘制正态分布曲线

    # 显示额外的统计信息
    plt.legend()
    plt.figtext(0.15, 0.85, f'SD: {std_dev:.2f}', ha='left', fontsize=10, color='blue')
    plt.figtext(0.15, 0.80, f'Min: {min_val:.2f}', ha='left', fontsize=10, color='blue')
    plt.figtext(0.15, 0.75, f'Max: {max_val:.2f}', ha='left', fontsize=10, color='blue')
    plt.figtext(0.15, 0.70, f'IQR: {iqr:.2f}', ha='left', fontsize=10, color='blue')
    plt.figtext(0.15, 0.65, f'N: {n}', ha='left', fontsize=10, color='blue')

    # 调整图像布局,确保所有元素居中
    plt.tight_layout()
        如果您喜欢我们的文章,欢迎关注
      更多科研干货点击👇,输入关键词搜索🔍


      叮当学术
      📚零零碎碎的科研学习记录~🔬科研本沉闷,但跑起来有风。
       最新文章