用Python绘制埃奇沃思盒:无差异曲线与帕累托最优可视化

发布时间:2026/10/13 17:38:29

用Python绘制埃奇沃思盒:无差异曲线与帕累托最优可视化 很多人学微观经济学的时候第一次接触埃奇沃思盒Edgeworth Box都会觉得有点抽象。两条坐标轴、两个消费者、两种商品、一堆弯弯曲曲的无差异曲线要全靠手绘来理解交换经济里的帕累托最优确实挺费劲。我当年也是这么过来的直到后来自己动手写代码才发现把这个盒子画出来、动起来比看十页教科书都有用。这篇博文就用Python核心库matplotlib带你一步步把埃奇沃思盒画出来顺便把背后的一般均衡思想也聊透。这个内容适合几类人看正在学中级微观经济学、被交换经济模型绕晕的学生想用可视化辅助研究或备课的经济学研究者以及Python刚入门、想找点有意思的绘图项目练手的读者。我会把原理、代码和踩过的坑都放在一起你照着敲一遍基本就彻底理解了。1. 内容整体设计与思路拆解1.1 埃奇沃思盒到底是什么先花点时间把埃奇沃思盒本身说清楚。它是英国经济学家埃奇沃思Francis Ysidro Edgeworth提出的一种分析工具用来研究两个消费者、两种商品、总量固定的纯交换经济。盒子的宽度代表商品X的总量高度代表商品Y的总量左下角是消费者A的原点右上角是消费者B的原点坐标系是反向的。盒子里每个点都代表一种分配方案A获得多少X和YB获得剩下的部分两者之和恰好等于社会总禀赋。这一点是整个模型的基石——没有生产只有交换总量被限制死了。在盒子里画出A和B各自的无差异曲线族之后就能讨论“哪些分配是有效率的”。有效率意味着不可能在不损害任何一方的条件下让另一个人变得更好这种分配对应的点正好是两组无差异曲线的切点。把这些切点连起来就得到一条从A原点到B原点的曲线叫做契约曲线Contract Curve也叫帕累托集。有意思的是这条线上的点只是“有效率”但未必“公平”。实际成交点落在哪里取决于双方的初始禀赋和议价能力。埃奇沃思盒的强大之处就在于你可以在同一张图里把这些经济学概念全部可视化出来。1.2 为什么用Python而不是手绘手绘埃奇沃思盒当然是每个经济学学生的基本功但手绘有几个天然的短板第一无差异曲线族很难画整齐曲线多了以后全是乱线第二切点位置的判断依赖直觉误差非常大第三想对比不同效用函数或者不同初始禀赋的场景就要重新画一张图效率极低。用Python画埃奇沃思盒核心优势就是参数化了。效用函数一变、初始禀赋一变、总量一变重新运行脚本就得到新的图。而且你可以很容易地在图里叠加多个元素——无差异曲线、禀赋点、契约曲线、交换路径箭头手绘几乎不可能做到这种信息密度。Python生态里做这件事的主力工具是matplotlib。它不是专门为经济学设计的但恰恰因为通用反而可以自由组织图形对象。加上numpy做数值计算毫无压力。注意我也见过有人用Desmos或者GeoGebra在线工具画但那些工具定制性弱且不容易批量出图。如果你需要把图插进论文、课件甚至网页给自己做笔记matplotlib才是自由度最高的选择。1.3 核心图形元素拆解一张完整的埃奇沃思盒图至少需要这几个元素底部和左侧坐标轴表示A的消费数量顶部和右侧坐标轴表示B的消费数量盒子的矩形区域本身代表总禀赋约束A的无差异曲线族从A原点出发向左上凸B的无差异曲线族从B原点出发向右下凸这里比较容易搞混因为B的原点在右上角初始禀赋点W以及经过W的两条无差异曲线围成的“互利交换空间”核Core。如果你想展示交换结果还需要画出契约曲线。我的经验是先画盒子框架再画无差异曲线最后叠加点和曲线。分图层画出了问题也好排查。2. 核心细节解析与实操要点2.1 坐标系统与函数轴的技巧画埃奇沃思盒最核心也最容易被新人卡住的地方就是坐标系转换。A的坐标从(0,0)到(总量X, 总量Y)这很直观但B的坐标完全相反B拥有的X数量要从盒子右边的边界向左数Y数量要从盒子上边界向下数。在matplotlib里怎么实现这个“反向观察”最直接的办法不是真的去翻转坐标轴而是在数据层面做换算。例如总量为(X_total, Y_total)B消费的X数量是X_b它对应的绘图坐标就是X_total - X_b。同理无差异曲线也不能全部以左下角为原点直接绘制。A的曲线用标准坐标系计算B的曲线则需要先把B的数据点取负值偏移让B的“原点”落在盒子右上角。这一步如果理解不到位画出来的B曲线会完全错位我最初就栽在这里图看起来就像两堆毫无关系的散点。2.2 无差异曲线族怎么生成无差异曲线的形状由效用函数决定。教科书最常用的柯布-道格拉斯效用函数Cobb-DouglasU(X,Y) X^α · Y^(1-α)。给定一个效用水平U₀解出Y关于X的表达式Y (U₀ / X^α)^(1/(1-α))。用numpy生成一组等间距的U值就能画出同一条效用水平下对应的整条曲线用多组U值就得到无差异曲线族。我自己的习惯是用np.linspace(1, 10, 8)这类方式生成效用水平序列这样图上的曲线族疏密适中又不至于相互重叠。如果你用固定步长生成U值靠近原点的地方会非常密集看图的时候什么都分辨不出来。2.3 工具版本与选型建议画这种图建议直接用matplotlib的面向对象接口plt.subplots不要用纯plt.plot那一套因为你需要频繁在同一个坐标系里叠加元素、设置不同轴标签面向对象方式让代码结构更清晰后期调整也更顺手。numpy是必须的曲线数值计算不能没有它。如果以后想把埃奇沃思盒做成交互式的可以在matplotlib的基础上加ipywidgets用滑块调效用参数和初始禀赋做到即时更新。我后面会简单提一下这个方向但这篇先用静态图把逻辑讲透。3. 实操过程与核心环节实现3.1 第一步设定参数与画盒子先把经济环境定义清楚。比如某经济体里有两个消费者A和B两种商品X和Y社会总禀赋也就是盒子尺寸设为X_total10, Y_total10A和B的初始禀赋为W_A(6, 4)W_B(4, 6)。代码里先把盒子的长方形框架画出来。盒子左下角对应A的原点右上角对应B的原点。我在图里会标注“消费者A”和“消费者B”各自的原点位置避免读者看图时迷失方向。import numpy as np import matplotlib.pyplot as plt X_total 10 Y_total 10 W_A np.array([6, 4]) W_B np.array([X_total, Y_total]) - W_A fig, ax plt.subplots(figsize(7, 7)) ax.plot([0, X_total, X_total, 0, 0], [0, 0, Y_total, Y_total, 0], k-, lw1.5) ax.set_xlim(0, X_total) ax.set_ylim(0, Y_total) ax.set_xlabel(Good X for A →) ax.set_ylabel(Good Y for A ↑) ax.set_title(Edgeworth Box) plt.show()这段代码跑出来就是最简单的空盒子。注意我用set_xlim把视口限制在盒子范围内这是为了避免坐标轴的延展超出盒子边界让图形比例失调。3.2 第二步生成A的无差异曲线先定义柯布-道格拉斯的逆函数给定效用水平UX取值数组计算对应的Y。这里需要注意X不能为0否则对数/幂运算会出现除零或无穷值所以X从0.01开始取。A的效用权重α我设为0.5意味着A对两种商品的偏好相同对称偏好。def indifference_curve(eff_level, alpha, x_vals): if alpha 1: return eff_level / x_vals return (eff_level / (x_vals**alpha)) ** (1 / (1 - alpha)) x_grid np.linspace(0.01, X_total, 300) for eff in [2, 4, 6, 8, 10, 12]: y_vals indifference_curve(eff, 0.5, x_grid) ax.plot(x_grid, y_vals, b-, alpha0.7, labelA if eff 2 else )这条曲线的含义是对A来说这条线上所有(X,Y)组合带来的效用相同。曲线越远离A的原点效用越高。3.3 第三步生成B的无差异曲线核心难点B的原点在右上角不能直接复用A的绘图坐标。正确的做法是先站在B的视角以B的原点为“左下角”生成曲线数值然后把这些数值映射到A的坐标系里。具体逻辑如果B消费X_b那么在A坐标系里的位置是X_total - X_b如果B消费Y_b在A坐标系里的位置是Y_total - Y_b。所以B曲线的逻辑是for eff in [2, 4, 6, 8, 10, 12]: y_b indifference_curve(eff, 0.5, x_grid) x_plot X_total - x_grid y_plot Y_total - y_b ax.plot(x_plot, y_plot, r--, alpha0.7, labelB if eff 2 else )注意这里有两个容易出错的地方。第一x_grid是B视角的X消费量从0.01到X_total第二x_plot和y_plot才是绘制使用的坐标。如果你直接拿y_b去plotB的曲线会从盒子左上角冒出来完全错位。从视觉上看B的每一元效用曲线都是红色的虚线和A的蓝色实线交叉。两组曲线的切点肉眼就能找出来这就是帕累托最优点的雏形。提示如果想强调某两条曲线在初始禀赋点相交只需把eff替换成该点的实际效用值即可。效用值计算公式是U X^0.5 * Y^0.5直接用numpy算。3.4 第四步标注初始禀赋点与核心区域初始禀赋W_A(6,4)对应W_B(4,6)。在图上用一个黑色星号标注并添加文字说明。然后分别计算A在W点的效用水平B在W点的效用水平把对应两条无差异曲线高亮出来。U_A_W np.sqrt(W_A[0] * W_A[1]) U_B_W np.sqrt(W_B[0] * W_B[1]) y_A_w indifference_curve(U_A_W, 0.5, x_grid) ax.plot(x_grid, y_A_w, b-, lw2.5, alpha0.9) y_B_w indifference_curve(U_B_W, 0.5, x_grid) ax.plot(X_total - x_grid, Y_total - y_B_w, r--, lw2.5, alpha0.9) ax.plot(*W_A, k*, markersize15) ax.annotate(W (Endowment), xyW_A, xytext(6.5, 5.2), arrowpropsdict(arrowstyle-, colorblack))经过W的两条无差异曲线围成的区域就是互利交换的“核”。在这个区域里的任一点A和B比初始状态都至少不下降且至少有一方严格变好。我通常用fill_between把这个区域填充出来直观冲击力很强。# 求高亮曲线在x_grid上的公共区间 common_x x_grid lower np.minimum(y_A_w, Y_total - y_B_w) upper np.maximum(y_A_w, Y_total - y_B_w) # 填充两条高亮曲线之间的区域 ax.fill_between(common_x, y_A_w, Y_total - y_B_w, where(y_A_w Y_total - y_B_w), colorgray, alpha0.3, labelCore)严格来说核的边界就是过W的这两条无差异曲线区域内所有分配都是双方自愿交换可能达成的结果。3.5 第五步画契约曲线契约曲线是A、B无差异曲线所有切点的集合。对柯布-道格拉斯效用函数来说切点条件等价于边际替代率相等。MRS_A (α/(1-α))·(Y/X)MRS_B用B视角计算时要小心偏置。推导后可以得到契约曲线的解析式。当α_A 0.5α_B 0.5时契约曲线是一条从A原点到B原点的直线Y X。这一点非常特殊因此我通常再用一个非对称例子来展示曲线形态比如让α_A0.7α_B0.3这时契约曲线会变成一条弧线。alpha_A 0.7 alpha_B 0.3 x_vals_cc np.linspace(0.1, X_total - 0.1, 200) # 契约曲线两消费者MRS相等的点 y_vals_cc (alpha_A/(1-alpha_A)) * (alpha_B/(1-alpha_B)) * x_vals_cc y_vals_cc y_vals_cc / (1 (alpha_A/(1-alpha_A)) * (alpha_B/(1-alpha_B))) ax.plot(x_vals_cc, y_vals_cc, g-, lw2, labelContract Curve)这里我不展开数学推导但你要知道逻辑链条A的MRS等于B的MRS再加上资源约束X_A X_B X_total、Y_A Y_B Y_total联立求解就能得到这条线。3.6 第六步完整的图与导出把前面几步整合到一个脚本里最终输出一张完整的埃奇沃思盒图。注意图例、标题、坐标轴标签都要齐全。导出时用dpi300的PNG或者直接存SVG方便插入论文或课件。plt.legend(locupper right) plt.tight_layout() plt.savefig(edgeworth_box.png, dpi300) plt.show()如果你像我一样经常需要对比参数建议直接把参数区块定义成字典放函数里封装好。下面是一个更工程化的写法。def draw_edgeworth_box(X_total10, Y_total10, W_A(6, 4), alpha_A0.5, alpha_B0.5, eff_levels[2,4,6,8,10,12]): W_B (X_total - W_A[0], Y_total - W_A[1]) fig, ax plt.subplots(figsize(7, 7)) ... return fig, ax这样之后想画十张八张对比图只是改参数的问题不需要重复复制代码。4. 常见问题与排查技巧实录4.1 B的无差异曲线位置错乱这是评论区最经常出现的问题。现象是红色虚线跑到了盒子外面或者和蓝色实线方向完全不匹配。原因几乎都是坐标转换错误。请记住B的曲线生成时x_grid代表的是B视角的X消费量这个值和A坐标系的关系是互补。任何一条B曲线上的点绘制坐标都要经过X_total - 和Y_total - 的换算缺一不可。另一种情况是x_grid端点取了0导致曲线在端点发散看起来整条线飞出去了。把起点改成0.01、终点改成X_total - 0.01问题就消失了。4.2 曲线族太密或太疏效用等级序列的生成方式直接影响可读性。如果你用np.linspace(1, 20, 100)图上会有100条线密集到完全看不出形状用np.linspace(1, 10, 5)又太稀疏切点不好找。我个人的经验是8到10条曲线最合适。效用等级用2到12之间取8个点视觉密度刚刚好。4.3 填充核区域失败fill_between要求两条曲线都定义在同一个x网格上而且where条件的逻辑不能搞反。我建议先把两条高亮曲线分别存成数组再检查两者的大小关系确认后再填充。打印几组值对照检查比自己盯着图猜要高效得多。4.4 图例和图例框遮挡曲线matplotlib默认的图例位置在右上角但埃奇沃思盒往往右上角正好是B的高效用区域会挡住重要图形。我习惯把图例放在盒子外面下方或者放在左下角空白处。如果放在图外记得用bbox_to_anchor参数。4.5 存出来的图字太小存图前检查figsize。如果你在屏幕上显示时觉得字号合适导出时很可能因为默认figsize是6×4英寸而显得很小。建议figsize直接设成(8,8)字体大小用fontsize参数统一设置导出dpi300时依然清晰。5. 交互式方向与扩展思路静态图能解决“理解”问题但如果你想探索“如果效用参数变了会怎样”静态图就不够用了。我强烈建议你做一个交互式版本用ipywidgets加两个滑块一个控制α_A一个控制α_B每动一下滑块图就重新绘制。这个扩展项目很值得做因为参数对契约曲线形状的影响非常直观。比如α_A和α_B差别越大契约曲线弯得越厉害差别为0时契约曲线就是对角线。这个“眼见为实”的过程比任何文字推导都有说服力。你还可以扩展成多期交换的动态模拟。给双方设定一个具体的“交换路径”从W点逐步走向契约线上某个交易结果用动画matplotlib.animation展示过程。这适用于讲价格调整机制或瓦尔拉斯试探过程我见过有人做了之后课堂效果非常好。如果数据是真实的比如实验经济学或者调查数据你还可以把实际观察到的交易结果散布在盒子里对比理论预测点做教学演示的时候非常震撼。6. 关于代码风格的一点反思画埃奇沃思盒这个任务规模不大但代码风格会影响之后扩展的体验。我吃过亏的地方是一开始把所有画图命令全部罗列在脚本里改一个参数就要全局搜索替换后来全部重构为函数才舒服。建议你一开始就按“参数定义-数据计算-绘图-标注-导出”五个区块组织代码区块之间用空行和注释分割。哪怕只有几十行这种结构也值得建立。等画交互式版本、多子图对比版本时你会感谢自己当初的克制。另外一个建议数值计算和画图分开。先把所有的曲线数值都算好放在变量里再集中画图。这样遇到调试问题可以先用print看看数据是否正确再判断是不是绘图配置的问题排查路径清晰很多。在这篇博文里我用matplotlibnumpy把埃奇沃思盒从空框架一步步画成了包含无差异曲线族、初始禀赋点、核和契约曲线的完整模型图。重点放在B消费者坐标转换、曲线生成和常见错误排查上因为这些都是实操中最容易卡住的地方。按这个流程走完一遍你既掌握了埃奇沃思盒的数学逻辑也顺手练熟了Python绘图的基本功。如果你自己跑代码时还有哪一步不太顺大概率是坐标补数或者参数边界的问题按第4部分对照检查就行。
延伸阅读

更多相关文章

2026/10/13 17:38:29

求解坐标转换矩阵的奇异值分解法:原理与C++实现

做点云配准、三维重建、机械臂手眼标定这些事儿,打到最后基本都会撞见同一个数学问题:已知两组对应的三维点,求坐标转换矩阵——也就是旋转矩阵 R 和平移向量 t。项目标题里说的“求坐标转换矩阵之奇异值分解法”,就是这个问题的标…

2026/10/13 17:38:29

VMD算法在海洋内波临界反射分析中的MATLAB实现

1. 项目背景与核心问题在海洋动力学研究中,层状流体中的内波现象一直是备受关注的课题。临界反射内波作为内波与海底地形相互作用时产生的一种特殊波动形式,其准确估计对于理解海洋能量传递、混合过程以及水下声学传播特性具有重要意义。传统的内波分析方…

2026/10/13 17:38:29

OpenClaw智能工作流引擎:提升职场效率与压力管理

1. 项目概述:当效率工具遇上职场压力管理2026年的职场环境正在经历一场静默革命。随着混合办公模式成为主流,工作与生活的界限愈发模糊,一个令人不安的数据显示:78%的上班族每天要处理来自5个以上沟通平台的信息,平均每…

2026/10/14 0:05:34

小波包能量谱原理与MATLAB实现:从频带分解到故障特征提取

简介:小波包能量谱MATLAB程序包面向信号处理方向的学习者与工程技术人员,用于对非平稳信号进行精细的时频能量分析,在机械故障诊断、噪声滤除等场景中具有实用价值。压缩包共4个文件,体积仅五十多KB,其中包含一个用于小…

2026/10/14 0:05:34

C语言大作业避坑指南:从编译器到现场验收的完整实战

简介:西工大C语言大作业完整项目包,覆盖绘制杨辉三角与借书方案两大经典课题。杨辉三角部分以数组与多层循环为核心,通过条件判断控制奇偶行格式,借助printf完成等腰三角形的排版输出,可直观体会二项式系数的递推规律&…

2026/10/14 0:05:34

python的机器人基础原理工业场景模拟第十三篇:焊接产线仿真,计算雅可比矩阵行列式,依据数值判断当前构型是否靠近奇异位形。

《Python机器人基础原理》第十三篇:焊接产线仿真——计算雅可比矩阵行列式,依据数值判断当前构型是否靠近奇异位形1. 实际工业应用场景周五上午,某新能源汽车电池托盘焊接产线。一台4-DOF关节型工业机械臂搭载MIG焊枪,对托盘铝合金…

2026/10/14 0:05:34

词根拆解技术:提升信息检索效率的核心方法

1. 信息检索中的词根拆解技术背景在信息爆炸时代,如何从海量文本中快速定位目标内容成为关键挑战。传统的关键词匹配方法存在明显局限:当用户输入"苹果"时,系统无法区分水果公司还是水果本身。词根拆解技术正是为了解决这一痛点而生…

2026/10/14 0:05:34

道路缺陷检测数据集YOLO训练避坑指南

简介:面向道路缺陷检测场景的大型目标检测数据集,包含约一万四千张训练图像、二百六十张验证图像和一千张测试图像,标签已转为YOLO格式,覆盖四类常见道路缺陷,可直接用于YOLO全系列网络训练。压缩包采用7z格式&#xf…

2026/10/14 0:00:33

SAP固定资产操作手册:从建卡到年结的完整指南

简介:《SAP固定资产操作手册》是一份面向SAP FI顾问、财务骨干及系统运维人员的实操指南,聚焦固定资产从新增、使用到报废的全生命周期管理,解决资产主数据不规范、购置入账流程不清晰、月末折旧易错等常见问题。文档以56页篇幅系统覆盖资产主…

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/13 17:09:18

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/14 0:00:33

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:33

macOS/iOS高精度计时:mach_absolute_time原理与实战

1. 项目概述:为什么mach_absolute_time是 macOS/iOS 时间测量的“黄金标准”在 macOS 和 iOS 开发中,我见过太多人用CFAbsoluteTimeGetCurrent()或NSDate.timeIntervalSinceReferenceDate做性能打点,结果在高精度场景下被系统时钟跳变、NTP 同…

2026/10/14 0:00:33

SCORM课件演示与测试全解析:从API通信到自动化验证

简介:这是一套遵循SCORM标准的交互式课件演示与测试资源,面向E-Learning课程开发者、LMS平台测试人员及在线教学从业者,用于验证课件在不同学习管理系统中的识别、传递与跟踪能力。压缩包共28个文件,约12.07MB,以swf动…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑