Python实现损益同期对比分析:Matplotlib与Plotly打造竖屏财报看板

Python实现损益同期对比分析:Matplotlib与Plotly打造竖屏财报看板 最近在做月度经营分析报表的时候我遇到一个很实际的场景领导要求在手机端直接打开一张损益表的总览图发到工作群里就能快速看明白当期经营情况。传统横屏图表在手机上一压缩字看不清、数据对不上非常尴尬。于是我用 Python 重新整理了一套损益同期对比分析的综合图表按 9:16 的竖屏比例输出并把营业收入、净利润、毛利率、费用率、利润瀑布图整合到一张图上后面又用 Plotly 做了一个可在手机浏览器交互查看的 HTML 版本。这篇文章就把整套实现过程整理出来从数据口径、画布规划、Matplotlib 绘制到 Plotly 交互看板都给出完整代码和避坑说明。无论你是做财务数据分析的 Python 开发者还是需要定期输出移动端汇报图表的分析师都可以直接沿用这套思路。即使只是新手也能按照文章里的步骤把模拟数据替换成自己的损益表数据快速生成一张能用于汇报的竖屏对比图表。1. 背景与核心概念1.1 什么是损益同期对比分析损益表也叫利润表反映的是一家企业在一定期间内的收入、成本、费用和利润情况。它和资产负债表、现金流量表并称为三大财务报表但损益表更侧重于“当期经营成果”可以说是管理层最频繁查看的一张表。损益同期对比分析核心思路就是拿当期数据和去年同期数据做对比观察收入是增长还是下滑、成本是否失控、费用率有没有上升、净利润是否改善。常见的对比口径有三个同比与上年同期比较例如 2024 年 6 月对比 2023 年 6 月主要用于消除季节性波动。环比与上一个周期比较例如 2024 年 6 月对比 2024 年 5 月适合观察短期趋势。预算差异与年初预算目标比较例如 2024 年上半年实际与预算的差异适合追踪目标达成率。本文的示例以“同比”为主线展示 2024 年上半年与 2023 年同期的损益对比。原因是同比受季节影响最小在管理层汇报中也是最常见的一种口径。很多新手容易把同比和环比混在一起出一张图里既有同比增长率又有环比增长率最后看板变得很难解读。我的建议是一张综合图只聚焦一个对比口径。如果既想看同比又看环比可以用两个页签分别展示不要堆在同一张竖屏图里。1.2 为什么需要综合图表这里的“综合图表”不是指一张单一图表而是把多个相互关联的图表组合成一个 Dashboard常见内容包括KPI 指标卡营业收入、净利润、毛利率、费用率等核心指标。月度对比柱状图展示 1 到 6 月每个月的收入或利润变动。瀑布图解释本期净利润相比同期发生变化的原因。结论文字区把图表结论直接写出来方便阅读者快速理解。综合图表的价值在于读者不用在多个 Excel Sheet 或 PPT 页面之间来回切换一张图就能完成“数据概览 → 趋势判断 → 原因拆解 → 结论输出”的完整阅读链路。1.3 竖屏版图表的适用场景竖屏版图表最早来自移动端适配需求。随着微信、钉钉、飞书等移动办公工具成为日常汇报渠道越来越多的图表需要在手机端查看。横屏图表在手机上的阅读体验较差主要原因有两个文字被等比缩小后难以辨识。用户需要不断横向滚动才能看全内容。竖屏版图表通常采用 9:16 或 3:4 的画布比例配合自上而下的信息流布局手机用户无需缩放就能完整浏览。在制作财务汇报图表时可以优先把竖屏图导出为图片发到工作群同时保留交互版 HTML 用于需要下钻查看明细的场景。2. 环境准备与工具选型2.1 环境依赖说明本文以 Python 3.8 以上版本为例主要依赖以下库库名称用途pandas数据处理与汇总numpy数值计算matplotlib绘制静态竖屏图表plotly生成可交互 HTML 看板如果还没有安装这些库可以在命令行执行pip install pandas numpy matplotlib plotly版本方面Matplotlib 3.5 以上、Plotly 5.x 以上都能运行本文代码。不同版本对 API 的影响很小如果遇到个别方法参数不一致以你自己环境的实际版本为准。2.2 常见实现方案选型方案优点缺点适用场景Excel/WPS 图表上手门槛低竖屏模板少自动化能力弱临时报表Python Matplotlib可编程、可控性强交互能力弱批量输出图片Python Plotly交互性强、支持移动端颜色风格需要额外配置网页看板Power BI / Tableau仪表板能力强部分环境需要授权账号企业级 BI 看板本文重点讲解 Python 方案因为它的组合成本最低一份数据既能输出静态竖屏图也能生成交互式 HTML还能批量复用。2.3 项目结构规划为了保持代码可维护性建议按下面的目录组织pnl_dashboard/ ├── data_prepare.py # 数据准备与指标计算 ├── dashboard_static.py # Matplotlib 竖屏静态图 ├── dashboard_interactive.py # Plotly 交互看板 └── output/ ├── 损益同期对比分析看板_竖屏版.png └── 损益同期对比分析看板_交互版.html数据准备和绘图逻辑分开写后续如果接上真实数据库只需要替换data_prepare.py不需要改动绘图部分。3. 数据集设计与指标口径3.1 模拟业务数据为了演示我构造了一家制造企业 2023 年和 2024 年 1 到 6 月的损益数据。单位统一为万元字段包括营业收入、营业成本、销售费用、管理费用、研发费用。# 文件data_prepare.py import pandas as pd import numpy as np # 模拟 2023 和 2024 年 1-6 月损益数据 months [1月, 2月, 3月, 4月, 5月, 6月] df pd.DataFrame({ 月份: months, 收入_2023: [320, 340, 360, 350, 380, 400], 收入_2024: [365, 385, 410, 402, 435, 462], 成本_2023: [205, 216, 228, 222, 240, 252], 成本_2024: [228, 240, 258, 252, 268, 284], 销售费用_2023: [30, 32, 33, 31, 35, 36], 销售费用_2024: [34, 36, 38, 36, 40, 42], 管理费用_2023: [22, 24, 23, 25, 26, 28], 管理费用_2024: [25, 27, 28, 29, 30, 31], 研发费用_2023: [28, 30, 32, 30, 33, 35], 研发费用_2024: [36, 38, 40, 39, 42, 44], }) for year in [2023, 2024]: df[f毛利_{year}] df[f收入_{year}] - df[f成本_{year}] df[f总费用_{year}] df[f销售费用_{year}] df[f管理费用_{year}] df[f研发费用_{year}] df[f净利润_{year}] df[f毛利_{year}] - df[f总费用_{year}]这里的企业数据是模拟数据主要目的是演示完整的指标计算和绘图过程。读者在实际项目中需要把这一段替换成自己从财务系统导出的真实数据并且在使用前经过必要的脱敏和审批。3.2 指标计算口径接下来计算各科目的上半年累计值和同比指标。这里的毛利率定义为“毛利 / 营业收入”期间费用率定义为“三项费用合计 / 营业收入”。def total(col): return df[col].sum() revenue_2023 total(收入_2023) revenue_2024 total(收入_2024) profit_2023 total(净利润_2023) profit_2024 total(净利润_2024) gross_2023 total(毛利_2023) gross_2024 total(毛利_2024) expense_2023 total(总费用_2023) expense_2024 total(总费用_2024) rev_yoy (revenue_2024 / revenue_2023 - 1) * 100 profit_yoy (profit_2024 / profit_2023 - 1) * 100 gross_margin_2023 gross_2023 / revenue_2023 * 100 gross_margin_2024 gross_2024 / revenue_2024 * 100 expense_rate_2023 expense_2023 / revenue_2023 * 100 expense_rate_2024 expense_2024 / revenue_2024 * 100最后得到的汇总结果如下指标2023 年同期2024 年本期同比变化营业收入2150 万元2459 万元14.37%营业成本1363 万元1530 万元12.25%毛利787 万元929 万元18.04%期间费用533 万元635 万元19.14%净利润254 万元294 万元15.75%毛利率36.60%37.78%1.18pp期间费用率24.79%25.82%1.03pp在财务分析中绝对值变化和比率变化是两套信息。例如收入同比增长 14.37%看起来不错但费用率同时上升 1.03 个百分点说明费用的增长速度超过收入增长速度。如果只看收入可能会忽略成本费用端的风险。这也是为什么综合图表必须同时展示收入和利润相关指标不能只画一根收入柱状图。3.3 瀑布图的口径说明利润桥瀑布图是同比分析里很直观的一张图用来解释“净利润从 254 万元变为 294 万元”的原因。这里采用一个简化的单变量归因模型起始为 2023 年同期净利润。毛利同比增加额作为正向贡献。期间费用同比增加额作为负向贡献。最终得到 2024 年本期净利润。也就是说净利润的变动被拆解为毛利变动和期间费用变动两个因素。这种拆法在财务上并不算精细因为它没有进一步区分收入量和价格的影响也没有拆分产品的结构变化。但作为日常汇报中的图表它足以回答“利润变化主要由哪块驱动”的问题。如果要做严格的利润桥分析建议结合业务端的量价数据进行多因素分解。4. 完整实战生成损益同期对比竖屏图这一节是全文核心。我会用 Matplotlib 生成一张竖屏综合图表从上到下依次是标题、KPI 指标带、月度收入对比图、月度净利润对比图、利润桥瀑布图、结论文字区。4.1 创建竖屏画布竖屏图的重点是画布比例。我采用figsize(9, 16)接近手机屏幕的 9:16 比例再通过 GridSpec 控制每一块区域的高度占比。import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec plt.rcParams[font.sans-serif] [Microsoft YaHei, SimHei, PingFang SC, Noto Sans CJK SC] plt.rcParams[axes.unicode_minus] False fig plt.figure(figsize(9, 16), dpi150) gs gridspec.GridSpec(5, 2,