Python 实现 Excel 数据可视化:柱状图制作教程

张开发
2026/4/9 17:42:32 15 分钟阅读

分享文章

Python 实现 Excel 数据可视化:柱状图制作教程
小张是公司里做运营分析的每个月都要把销售数据整理成图表给老板做汇报。以前他都是手动在Excel里点来点去选数据范围、插入柱状图、调颜色、改字体一套操作下来至少半小时。碰上数据更新频繁的日子他得重复做三四遍同样的操作烦到想摔鼠标。有一天他跑来问我“有没有办法让Excel自动画图我每次数据格式都一样就是数值变了。”我说“用Python啊写一次脚本以后一键生成颜色字体你说了算还能批量处理。”他眼睛亮了。这篇文章就从这个场景出发聊聊怎么用Python和Excel配合优雅地画出各种柱状图。准备工具装三个库就够了Python操作Excel有几个成熟的库。最省事的是pandas它能直接读写Excel文件处理数据表格。画图交给matplotlib这个库几乎能画出所有你能想象到的图表。如果还想保留Excel公式或者调整格式可以加上openpyxl。装起来一句话的事情pip install pandas matplotlib openpyxl我习惯在Jupyter Notebook里调试这些代码因为能看到每一步的数据长什么样。如果你用普通.py文件也完全没问题。拿数据开刀从Excel读到pandas先看一个实际场景。假设有一张销售数据表叫sales.xlsx里面每个月每个产品的销售额月份产品A产品B产品C1月12095802月135102883月14811092用pandas读这个文件只需要一行import pandas as pd df pd.read_excel(sales.xlsx) print(df.head())head()方法能让你看一眼前几行数据确认读进来的格式对不对。pandas会自动把第一行当作列名后面每一行对应一个月份。第一张柱状图五步搞定数据在手里了画图其实就五步选数据、创建画布、画柱状图、加标题标签、显示或保存。import matplotlib.pyplot as plt # 把月份列作为横坐标的标签 months df[月份] # 遍历每一列产品分别画一组柱子 plt.bar(months, df[产品A], label产品A) plt.bar(months, df[产品B], label产品B) plt.bar(months, df[产品C], label产品C) # 加标签和标题 plt.xlabel(月份) plt.ylabel(销售额万元) plt.title(各产品月度销售对比) # 显示图例 plt.legend() # 展示图表 plt.show()跑完这段代码一张简单的分组柱状图就弹出来了。每个月份有三根柱子并排代表三个产品的销售额。这比在Excel里手动选区域、插入图表快多了。但还不够好看柱子颜色、字体大小、网格线都可以调。让图表好看一点细节决定质感默认的matplotlib图表长得很“学术”蓝橘色的柱子白色背景谈不上难看但也说不上精致。改几个参数就能大变样。# 设置中文字体不然图表里的中文会变成方框 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # 创建画布时指定尺寸和分辨率 fig, ax plt.subplots(figsize(10, 6), dpi100) # 画图时自定义颜色和透明度 ax.bar(months, df[产品A], label产品A, color#FF6B6B, alpha0.8) ax.bar(months, df[产品B], label产品B, color#4ECDC4, alpha0.8) ax.bar(months, df[产品C], label产品C, color#45B7D1, alpha0.8) # 添加网格线提升可读性 ax.grid(axisy, linestyle--, alpha0.5) # 在柱子上方显示数值 for i, (a, b, c) in enumerate(zip(df[产品A], df[产品B], df[产品C])): ax.text(i, a 2, str(a), hacenter, vabottom, fontsize9) ax.text(i, b 2, str(b), hacenter, vabottom, fontsize9) ax.text(i, c 2, str(c), hacenter, vabottom, fontsize9) plt.tight_layout() plt.show()alpha参数控制透明度多个柱子重叠时能看到后面的内容。grid加网格线能让数值对比更直观。text方法在柱子上方标了具体数字老板看图表时不用再猜这根柱子到底是多少。颜色代码用的是十六进制RGB格式比默认的颜色高级不少。可以在网上搜配色方案选一套自己看着舒服的。两种特殊柱状图应付不同场景有时候并排柱子太多了显得拥挤。可以换成堆叠柱状图每个月份的三根柱子叠在一起总高度就是三个产品的销售额之和。# 堆叠柱状图 fig, ax plt.subplots(figsize(10, 6)) ax.bar(months, df[产品A], label产品A, color#FF6B6B) ax.bar(months, df[产品B], bottomdf[产品A], label产品B, color#4ECDC4) ax.bar(months, df[产品C], bottomdf[产品A] df[产品B], label产品C, color#45B7D1) ax.set_ylabel(总销售额万元) ax.legend() plt.show()bottom参数决定了这根柱子从哪里开始堆叠。产品B的柱子底端是产品A的高度产品C的柱子底端是A加B的高度。这种图适合展示“总量”和“构成”的关系。还有一种需求是横向柱状图。当产品名称或者月份标签比较长时竖着放会挤在一起看不清。barh方法画横着的版本# 横向柱状图 ax.barh(months, df[产品A], label产品A) ax.barh(months, df[产品B], label产品B) ax.barh(months, df[产品C], label产品C)只是把bar换成了barhx轴和y轴的角色互换了。批量生成图表十分钟的工作变成十秒钟这才是Python真正的杀手锏。假设你有12个分公司的销售数据分别存在12个Excel文件里每个文件要生成一张柱状图。手动做的话打开、复制、粘贴、调整格式一上午就没了。用Python写个循环几秒钟跑完。import glob # 获取所有Excel文件 files glob.glob(分公司销售数据/*.xlsx) for file in files: df pd.read_excel(file) # 从文件名提取分公司名称用来命名输出的图片 company_name file.split(/)[-1].replace(.xlsx, ) fig, ax plt.subplots(figsize(10, 6)) ax.bar(df[月份], df[销售额], colorsteelblue) ax.set_title(f{company_name}月度销售情况) ax.set_xlabel(月份) ax.set_ylabel(销售额万元) # 不显示窗口直接保存文件 plt.savefig(f图表输出/{company_name}_柱状图.png, dpi150, bbox_inchestight) plt.close()这里有两个关键点。savefig代替show不弹窗口直接存图。bbox_inchestight能自动裁剪掉图表周围多余的空白。循环结束后指定文件夹里整整齐齐躺着12张图片每一张都格式统一、标题自动适配。把图表写回Excel方便分享有些人不想单独看图片文件希望图表直接嵌入到Excel表格里。这也能做到用openpyxl配合matplotlib。from openpyxl import Workbook from openpyxl.utils.dataframe import dataframe_to_rows from openpyxl.drawing.image import Image import io # 先把图表存到内存里的字节流不生成临时文件 buf io.BytesIO() plt.savefig(buf, formatpng, dpi100) buf.seek(0) # 新建Excel文件并写入数据 wb Workbook() ws wb.active # 将pandas数据写入工作表 for r in dataframe_to_rows(df, indexFalse, headerTrue): ws.append(r) # 插入图片 img Image(buf) img.width 400 img.height 300 ws.add_image(img, E2) # 放在E2单元格位置 wb.save(带图表的销售报表.xlsx)这样生成的文件别人打开就能直接看到数据和图表不需要额外发图片。几个让我踩过坑的小问题中文字体是最容易翻车的。matplotlib默认字体不支持中文画出来的图里汉字全是小方框。解决方案是提前设置字体用rcParams指定一个系统中存在的支持中文的字体。如果是在Linux服务器上跑可能需要先安装中文字体或者用fc-list :langzh命令查一下已安装的字体。数据列名不要有空格。pandas读取Excel后如果列名是“产品 A”这种带空格的调用df[产品 A]会报错。要么提前改好列名要么用df.columns [col.strip() for col in df.columns]批量清理。保存图表时如果中文变成了乱码试试plt.savefig之前再加一次字体设置。有时候前面设好了保存时却丢失了重新设置能解决。从手动到自动效率提升看得见小张后来用这套脚本每月做报表的时间从半小时压缩到了十秒钟。他只需要把最新的数据覆盖到Excel文件里双击运行脚本图表自动生成。他把脚本给了部门其他同事大家都很开心。数据可视化的核心价值不是图表多漂亮而是能不能快速准确地传达信息。当你重复做同一类图表超过三次就该考虑写脚本了。这不是偷懒是聪明地工作。Excel和Python不是替代关系是互补关系。Excel适合交互式探索数据Python适合批量化、自动化处理。两者结合威力翻倍。

更多文章