

本文共7个部分(获取方式在 “06 ”部分):
00.数据组织格式

01. 设置工作环境
# 1. 设置工作环境# ============================================================# 1.1 导入必要的库import osimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom matplotlib import rcParams# 1.2 设置工作空间os.chdir("D:/Desktop/Py科研绘图/Python论文插图绘制模板第2期-分组柱状图")
02. 数据读取与格式转换
# 2. 数据读取与格式转换# ============================================================# 2.1 读取 Excel 数据data_df = pd.read_excel("data.xlsx")# 2.2 将宽数据转换为长数据# 第1列为样本名称,第2到第6列为指标组id_vars = data_df.columns[0] # 第一列作为标识变量(样本名)value_vars = data_df.columns[1:6] # 第2到第6列为待熔化的列long_data = pd.melt(data_df,id_vars=[id_vars],value_vars=value_vars,var_name='Index_group',value_name='Value')

03. 绘制图形
# 3. 绘制图形# ============================================================# 3.1 图片大小(宽×高)fig, ax = plt.subplots(figsize=(9.5, 6.5))# 3.2 准备绘图所需参数categories = long_data[id_vars].unique() # X轴类别(样本)groups = long_data['Index_group'].unique() # 分组(Index_group)n_categories = len(categories)n_groups = len(groups)# 3.3 定义颜色colors = ["#105186", "#3D86B6", "#67B3DA", "#9DDAF2", "#CDEEF8"]# 3.4 设置柱子宽度和组内间距bar_width = 0.15 # 单个柱子的宽度group_gap = 0.75 # 组内柱子总宽度total_width = bar_width * n_groupsx = np.arange(n_categories) # 每个类别的基准位置# 3.5 绘制分组柱状图for i, (group, color) in enumerate(zip(groups, colors)):# 提取当前分组的数据subset = long_data[long_data['Index_group'] == group]# 确保数据顺序与 categories 一致values = [subset[subset[id_vars] == cat]['Value'].values[0] for cat in categories]# 计算每个柱子的偏移位置(居中于组内)offset = (i - (n_groups - 1) / 2) * bar_widthbars = ax.bar(x + offset,values,width=bar_width,color=color,edgecolor='none', # 柱子无边框linewidth=0.05,alpha=1.0,label=group)# 3.6 添加数值标签for i, (group, color) in enumerate(zip(groups, colors)):subset = long_data[long_data['Index_group'] == group]values = [subset[subset[id_vars] == cat]['Value'].values[0] for cat in categories]offset = (i - (n_groups - 1) / 2) * bar_widthfor j, val in enumerate(values):ax.text(x[j] + offset, # 数值标签X坐标val+0.01, # 数值标签Y坐标(柱顶高度+0.01)f'{val:.2f}', # 保留两位小数ha='center', # 水平对齐va='bottom', # 垂直对齐rotation=90, # 旋转角度fontsize=12, # 字体大小fontweight='bold', # 字体粗细(可选值:'light'、'normal'、'bold'、'heavy'、'black' 或数值 0-1000)fontfamily='DejaVu Serif', # 数值标签字体color='black' # 数值标签颜色)# 3.7 坐标轴范围、刻度、标题设置# 设置 Y 轴范围、刻度及格式# # 获取数据的最值,便于后续坐标轴设置(本示例中手动指定了范围,可忽略)# y_max = long_data['Value'].max()# y_min = long_data['Value'].min()ax.set_ylim(0, 0.40) # 纵轴范围ax.set_yticks(np.arange(0, 0.41, 0.05)) # 纵轴刻度(起始、停止、步长)ax.set_yticklabels([f'{tick:.2f}' for tick in np.arange(0, 0.41, 0.05)]) # 纵轴刻度小数位数# 设置 X 轴刻度及标签ax.set_xticks(x)ax.set_xticklabels(categories)# 设置坐标轴标题# 横轴标题ax.set_xlabel('X_Title', # 横轴标题fontsize=18, # 横轴标题字号fontstyle='normal', # 横轴标题字体样式(“normal”、“italic”)fontfamily='DejaVu Sans', # 横轴标题字体labelpad=8) # 横轴标题到坐标轴距离# 纵轴标题ax.set_ylabel('Y_Title', # 纵轴标题fontsize=18, # 纵轴标题字号fontstyle='normal', # 纵轴标题字体样式(“normal”、“italic”)fontfamily='DejaVu Sans', # 纵轴标题字体labelpad=8) # 纵轴标题到坐标轴距离
04. 调整细节
# 4. 调整细节(边框、网格线、刻度线、标题格式、图例样式等)# ============================================================# 4.1 隐藏上、右边框,并确保左、下边框为默认黑色、默认线宽ax.spines['top'].set_visible(False)ax.spines['right'].set_visible(False)# 4.2 设置左、下边框颜色为黑色(线宽不显式设置,即为默认值)ax.spines['left'].set_color('black')ax.spines['bottom'].set_color('black')# 4.3 网格线设置:仅保留 Y 轴主网格线,灰色、细线ax.set_axisbelow(True) # 将网格线置于柱状图下方ax.yaxis.grid(True, which='major', color='#e5e5e5', linewidth=1.5, linestyle='-')ax.yaxis.grid(False, which='minor') # 关闭次网格线ax.xaxis.grid(False) # 关闭 X 轴网格线# 4.4 刻度线设置ax.tick_params(axis='both', # 设置横纵轴刻度线(“x” 或 “y” 或 “both”)which='major', # 设置主刻度线length=5, # 刻度线长度direction='out' # 刻度线朝向(“in” 或 “out” 或 “inout”))# 单独设置 X 轴刻度标签格式for label in ax.get_xticklabels():label.set_fontfamily('DejaVu Sefif') # 字体label.set_fontsize(14) # 字号label.set_fontstyle('italic') # 字体样式(常规"normal";斜体“italic”)label.set_fontweight('bold') # 字体粗细(可选值:'light'、'normal'、'bold'、'heavy'、'black' 或数值 0-1000)label.set_color('black') # 字体颜色# 单独设置 Y 轴刻度标签格式for label in ax.get_yticklabels():label.set_fontfamily('DejaVu Serif') # 字体label.set_fontsize(14) # 字号label.set_fontstyle('italic') # 字体样式(常规“normal”;斜体“italic”)label.set_fontweight('bold') # 字体粗细(可选值:'light'、'normal'、'bold'、'heavy'、'black' 或数值 0-1000)label.set_color('black') # 字体颜色# 图例设置# 创建图例,放置在坐标轴右侧外部居中legend = ax.legend(frameon=False,handlelength=2.5, # 图例色块长度handletextpad=0.5, # 图例色块到文字距离loc='center left', # 图例的“左侧中心”作为对齐点bbox_to_anchor=(1.02, 0.5) # 对齐点位于坐标轴右侧边界外(x=1.02),y=0.5 即垂直居中)# 添加图例标题legend.set_title('Index') # 图例标题legend.get_title().set_fontfamily('DejaVu Sans') # 图例字体legend.get_title().set_fontsize(18) # 图例字体大小legend.get_title().set_fontweight('normal') # 图例字体粗细# 设置图例内部文字字体for text in legend.get_texts():text.set_family('DejaVu Sans') # 图例的字体text.set_size(18) # 图例的字体大小# 图形边距调整(不用动这里的参数)plt.subplots_adjust(left=0.1, right=0.95, top=0.9, bottom=0.1)
05. 图形导出
# 6. 保存与显示# ============================================================plt.tight_layout() # 确保所有标签、标题、图例等不会重叠或被裁剪plt.savefig('分组柱状图-Python.png', # 可保存为PNG、PDF、SVG、EPS等多格式dpi=300, # 分辨率bbox_inches='tight') # 控制保存时的边界裁剪范围plt.show()

06. 横向柱状图模板获取方式
往期推荐


联系我们


