Python处理Excel文件并绘制多组箱线图

如果需要,你可以提供数据格式、想要的数据处理结果、想使用的语言,我尽力提供帮助,你提供给我练手的机会!!!

本次处理数据为α-多样性中的“ACE、Simpson、Chao1、Shannon”,生成四组箱线图,每张箱线图涉及两组数据,并且在图中显示显著性标志。

需要用到的 Python库 有:matplotlib.gridspec.GridSpec、pandas、matplotlib.pyplot、numpy、scipy.stats.ttest_ind。

所需库介绍及用法:

matplotlib.gridspec.GridSpec:用来创建一个网格布局。

gs  = GridSpec(nrows, ncols, figure=None, left=None, bottom=None, right=None, top=None, 

                         wspace=None, hspace=None, width_ratios=None, height_ratios=None)

然后可以设置子图显示在哪个区域:gs[n] 或者 gs[r, c]

其中:nrows, ncols代表网格布局的行数和列数;figure代表子图绘制在哪张图形中;left, right, top, bottom可以定义子图范围(left值不能大于right值,bottom值不能大于top值);wspase,hspace可以定义子图间的宽度、高度空间;width_ratios,height_ratios定义列、行的宽度比率。

pandas:用来读取Excel文件。

data = pandas.read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None, squeeze=None, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, parse_dates=False, date_parser=None, thousands=None, decimal='.', comment=None, skipfooter=0, convert_float=None, mangle_dupe_cols=True, storage_options=None)

其中:io代表有效的字符串路径(Excel文件、xlrd工作簿、URL等);sheet_name代表处理Excel文件中哪一个sheet;header指定表头行号;names指定列名列表;index_col指定索引列号(其他参数可选进行设置)。

matplotlib.pyplot:用来绘制箱线图。

相对于 seaborn 来说,matplotlib具有更多的可操作性,自定义绘制时更加方便。但是在绘制箱线图时,Python的图例不会像R语言似的将图例绘制成箱子的形状(请注意)

numpy:支持大量的维度数组和矩阵运算,在本次示例中用于生成坐标位置列。

scipy.stats.ttest_ind:使用独立样本T检验方法生成显著性。

数据示例:

箱线图涉及到两组数据,因此会有两个类似的sheet,存储格式如下:

详细代码:

from matplotlib.gridspec import GridSpec
from scipy.stats import ttest_ind
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams.update({'font.size': 18})  # 设置全局字体大小为18

#添加显著性标记的自定义函数
def add_stat_annotation(ax, x1, x2, y, text, color='black'):
    ax.text((x1 + x2) * 0.5, y, text, ha='center', va='bottom', color=color)

data_path = '数据文件.xlsx'

# 创建一个图形
fig = plt.figure(figsize=(5, 12))
# 创建一个网格布局
gs = GridSpec(nrows=4, ncols=1, figure=fig)
#柱子宽度
bar_width = 0.2
#设置两组对比数据的柱子颜色(可以设置不同颜色或者相同颜色,但是要和柱子数量匹配)
colors1 = ['#1FB573'] * 3
colors2 = ['#F7931F'] * 3
#对比数据的所属类别
tags3 = ['A', 'B', 'C']
#当前子图位置
p = 0

#绘制子图,我的数据有四部分
for j in ['ACE', 'Simpson', 'Chao1', 'Shannon']:
    ax = fig.add_subplot(gs[p])
    #第一组数据,3个数据对应一个样本集,每个数据都是样本集中的一个平行样本
    df1 = pd.read_excel(data_path, sheet_name='data1', header=0)
    grouped_list1 = [df1[j].tolist()[m:m + 3] for m in range(0, len(df1[j]), 3)]
    #第二组数据,同上
    df2 = pd.read_excel(data_path, sheet_name='data2', header=0)
    grouped_list2 = [df2[j].tolist()[m:m + 3] for m in range(0, len(df2[j]), 3)]

    #第一组数据位置
    positions1 = np.arange(1, 4)  # 调整位置以避免重叠
    #第二组数据位置
    positions2 = np.arange(1, 4) + bar_width
    #横坐标标签位置
    positions3 = np.arange(1, 4) + bar_width * 0.5
    
    #绘制第一组数据的箱线图
    #showcaps=False:不显示两端的虚线
    #patch_artist=True:控制箱子颜色
    bp1 = ax.boxplot(grouped_list1, positions=positions1, widths=bar_width, patch_artist=True, showcaps=False, medianprops={'color': 'black'})
    for patch, color in zip(bp1['boxes'], colors1):
        patch.set_facecolor(color)
    #绘制第二组数据的箱线图
    bp2 = ax.boxplot(grouped_list2, positions=positions2, widths=bar_width, patch_artist=True, showcaps=False, medianprops={'color': 'black'})
    for patch, color in zip(bp2['boxes'], colors2):
        patch.set_facecolor(color)
    
    #设置标签位置及横坐标标签名称
    ax.set_xticks(positions3)
    ax.set_xticklabels(tags3)

    #设置纵轴的名字
    ax.set_ylabel(j + ' index')
    
    #为不同的子图设置不同的纵轴范围(为了子图更好的显示)
    if j == 'ACE':
        plt.ylim(2000, 30000)
    elif j == 'Simpson':
        plt.ylim(0.91, 1.05)
    elif j == 'Chao1':
        plt.ylim(2000, 20000)
    else:
        plt.ylim(8, 14)

    #设置显著性标记位置
    ylim = ax.get_ylim()
    y_sig = ylim[1] - (ylim[1] - ylim[0]) * 0.16
    
    # 计算显著性并添加标记
    for pos1, pos2, data1, data2 in zip(positions1, positions2, grouped_list1, grouped_list2):
        t_stat, p_val = ttest_ind(data1, data2)
        if p_val < 0.001:
            text = '***'
        elif p_val < 0.01:
            text = '**'
        elif p_val < 0.05:
            text = '*'
        else:
            text = None

        if text:  # 只在p值显著时添加标记
            add_stat_annotation(ax, pos1, pos2, y_sig, text)

    #只显示第一张子图的图例
    if p == 0:
        ax.legend([bp1["boxes"][0], bp2["boxes"][0]], ['data1', 'data1'], loc='upper left', bbox_to_anchor=(1, 1))#

    p = p + 1

plt.show()

箱线图示例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值