
做人群仿真的项目最累的不是建模也不是调参而是跑完那一刻对着满屏结果文件发呆。SimWalk 算完一个场景会给你几十种输出密度图、轨迹、疏散时间、服务水平统计……每一样都像是答案的一部分但又都不是现成的答案。这篇是 SimWalk 系列教程的第九篇专门讲结果分析与可视化。不管你是做地铁站疏散评估、大型活动应急预案还是商场动线优化只要你的工作流里用到了 SimWalk这篇都能帮上忙核心就一件事把跑出来的原始结果变成能拍板的结论也让外行一眼看懂仿真到底说了什么。我自己用 SimWalk 做了好几个实际项目踩过的坑和沉淀下来的方法下面一次性讲透。1. 结果分析之前先搞清楚SimWalk到底输出了什么1.1 五大类结果文件别拿到数据就晕SimWalk 不像普通计算软件只给一个汇总表它默认会输出一堆结果视图和数据文件。我用的是 SimWalk 4.x 版本界面功能名在不同版本里叫法可能不一样但原理大同小异。从实际项目经验来看最常用的输出可以分成五类每一类都有自己的使用场景和读取方法。首先是密度图Density Diagram。SimWalk 把场景网格化每个格子里统计行人存在时间的占比平均之后得到密度值用颜色体现。网格大小非常关键我通常设置 0.5 米乘 0.5 米太大会把瓶颈细节抹平太小则噪声偏大热力图会花成一片。密度图的颜色默认从蓝绿渐变到黄红蓝色代表几乎没人红色代表密度非常高。有一个小技巧在结果显示设置里把颜色范围手动固定不要用自动范围。否则你对比两个场景的时候会误读一个最大密度只有 1.0 的场景和一个最大密度到 3.0 的场景自动范围会让前者也红得不轻但实际上两码事。其次是流量图Flow Diagram。SimWalk 里可以画测量截面Section line统计通过这个截面的双向流量和总流量。流量图上的箭头方向是统计时间内行人移动的方向注意箭头是聚合结果不是单个行人。如果箭头在某个区域交叉打结说明动线冲突明显这就是需要重点优化的地方。流量数据是判断“通行能力够不够”的第一手证据比单纯看密度图要更接近问题本质。第三类是轨迹图Trajectories / Route Lines。每条线代表一个代理的路径可以按速度着色。轨迹图最容易暴露“绕路”问题在开阔区域出现密集的弧线说明人们没走最短路径很可能被障碍物、排队区或引导标识影响。轨迹线太多时画面会很乱我一般只显示 20% 左右的代理看起来干净趋势也清晰。第四类是疏散/行走时间结果。疏散场景里我最关心的是“最晚离开时间”和“95 百分位离场时间”。规范一般要求所有人离开时间但最后一个人的离场时间受随机因素影响很大所以我更爱看 95 分位更稳定。SimWalk 可以直接在结果面板里看也可以导出 CSV 自己统计。第五类是服务水平统计LOS Table。软件会按 Fruin 标准把每片区域的服务等级划分成 A 到 F用色块展示。密度阈值通常是A 级小于 0.31 人/平方米B 级 0.31 到 0.43C 级 0.43 到 0.72D 级 0.72 到 1.08E 级 1.08 到 2.17F 级大于 2.17。这个标准做报告非常好用直接说“某区域服务水平为 E人流量已经超过舒适范围”业主马上能理解。1.2 从数据到结论的分析逻辑把数字翻译成决策拿到这些输出之后怎么用我经常跟项目组说结果分析就做三件事找瓶颈、验状态、给结论。这三件事各有各的对应数据。找瓶颈主要看密度。密度超过 1.08 人/平方米时已经到 D 级人开始频繁调整速度走起来很不舒服超过 2.17 就是 F 级几乎堵死。SimWalk 密度图上这些区域会呈现红褐色一眼就能看到。但光看颜色还不够我一般会把最大密度对应的时间步长也找出来再配合流量图看这段时间通过瓶颈截面的通行量有没有断崖式下跌。如果密度高而流量也高那只是拥挤如果密度高而流量掉下去了那就是真堵车式停滞。验状态看速度和排队。SimWalk 能统计平均行走速度。如果某段通道平均速度低于每秒 0.5 米大概率已经形成拥堵。排队长度可以看轨迹是否在某处大量重合并长时间停滞。再把服务水平统计加上一个区域的舒适度就能量化成“能在报告里写数字”的结论。比如“候车厅入口处平均密度 1.30LOS 为 E平均步行速度下降到 0.42 米/秒队伍长度约 12 米”。给结论就是把疏散时间、密度、LOS、最大排队长度这些指标汇总成一张表对应到业主关心的合规性和体验问题。这个过程必须结合场景同样的密度在楼梯口和候车厅含义完全不同。所以我做分析时习惯把 SimWalk 结果分成两半左边是数值摘要右边是对应视图截图在报告里直接引用视图位置来定位问题。这个习惯救了我很多次因为很多业主只看图数字说再多也不如一张热力图直观。指标数据特征让我做的决策密度 1.5 人/㎡颜色偏红LOS E加宽通道、调整栏杆位置平均速度 0.4 m/s低于 0.5检查是否形成排队、出口是否阻塞轨迹严重重叠弧线集中在某一区域调整动线、增加引导标识疏散时间超标超过规范或甲方要求扩大出口宽度、增加疏散门两个出口流量差过大一侧 70%一侧 30%调整导向设施均衡出口利用2. SimWalk自带的可视化怎么用才最出效果2.1 密度热力图的正确打开方式SimWalk 自带的密度热力图是最常用的可视化工具但不是打开就完事。很多人直接把默认视图截图放进报告结果问题一大堆颜色范围没固定、网格太粗、时间段不对、没有叠加平面底图。做热力图我建议按这个顺序调先设网格尺寸再固定颜色标尺然后选择统计时间段最后叠加底图。网格尺寸前面提到了0.5 米左右比较合适。固定颜色标尺可以在结果属性里手工输入最大值比如把全局颜色标尺定为 0 到 3.0 人/平方米这样不同方案之间可以公平对比。时间段选择上SimWalk 默认做整个模拟周期的平均密度但瓶颈往往只出现在高峰期那几分钟所以我会额外打开逐时间步长的密度动画把红色区域出现的时间段记下来再单独导出那个时间段的数据。叠加底图也很关键。SimWalk 支持把 CAD 平面图或位图作为背景调成半透明再叠加热力图层。这样一来业主看报告时能对号入座知道哪片红色是安检区、哪片是楼梯口而不是对着一个抽象网格发呆。透明度我一般设置在 50% 左右太实会挡住底图太虚颜色又看不清楚。2.2 动态轨迹与流量箭头还原人群运动过程动态轨迹是我向甲方演示时最讨喜的功能。SimWalk 里可以播放整个模拟过程能看到行人从生成到离开的完整运动轨迹。播放速度建议从 1 倍开始把注意力放在容易出现冲突的区域。有些现象慢速播放时才能对得上时序比如闸机前排队你会看到轨迹在一个截面处逐渐重叠队伍长度随时间变长。这时候光靠一张静态热力图是讲不清楚“怎么堵的”只能靠动画。流量箭头更适合做“分时段分析”。我一般每 5 分钟截一张图看高峰人流方向的演变。比如地铁换乘通道早高峰和晚高峰的主导方向正好相反如果把整个时间段混在一起箭头会互相抵消得出的方向一点也不明确。分开截屏后才能看出原来的动线设计是否照顾了两个方向。轨迹图还有个用法是看速度分布。给轨迹按速度着色慢速区域自然显示为冷色调和密度图互相印证。如果密度图显示红色而轨迹速度并不低说明人流还在动只是拥挤如果轨迹速度也低那就是停滞排队问题更严重。2.3 结果报告与图表输出软件自带功能的上限SimWalk 自带报告功能可以生成 HTML 报告包含基本统计和图表。用来快速给同事看可以但正式交付给甲方时样式和深度都不够。我通常把 SimWalk 的报告当“过程文件”最终结论图表还是要自己加工。导出方面SimWalk 可以把密度云图作为图片导出也可以把数据导出为文本或 CSV再导入其他工具。我个人推荐至少保留三类导出物密度矩阵 CSV、轨迹 CSV、截面流量时间序列 CSV。这三样数据在手后续用 Python、Excel甚至前端图表库都能做很多事。如果你需要把 SimWalk 结果叠加到 CAD 或 GIS 里也可以把密度云图作为光栅图导出再对齐坐标放入 CAD。这样做疏散指示图、安全评估图非常方便。注意在导出前把不需要显示的图层全部关掉只保留密度和底图否则叠到 CAD 里会有一堆乱线。3. 把SimWalk结果接入外部可视化工具我的一套完整流程3.1 导出字段、时间步长与数据格式SimWalk 的导出选项比较多用之前一定要确认字段含义。最常见的是密度矩阵字段大致是时间步、网格 X、网格 Y、密度值。轨迹数据则是每个代理在不同时间的坐标、速度和状态。截面流量数据则是某个截面在连续时间步里的通过人数。时间步长要提前想好。SimWalk 内部计算步长可能很细但导出时为了控制文件体积可以每 2 秒采样一次。注意采样间隔太大会丢峰值我一般是先看模拟总时长如果模拟 5 分钟用 1 秒或 2 秒采样足够如果模拟半小时就按 5 秒采样。密度矩阵如果网格很多单次导出会非常大建议按区域导出不要整场景一次导完否则轻则文件几百兆重则直接卡死。我给一个典型的密度导出文件示例TimeStep,GridX,GridY,Density 0,1,1,0.00 2,1,1,0.12 4,1,1,0.35这个格式就是给 Python 用的。拿到的第一件事先看文件行数。如果行数和预期差距太大回模型里检查测量区是否覆盖了目标范围别急着往下算。3.2 用Python把密集数据变成决策表SimWalk 自带图表够用但要做定制分析、批量处理多工况Python 几乎是必须的。我一般用 Pandas 读 CSV然后算几个核心指标全局平均密度、最大密度时间点和位置、超过阈值的时间占比轨迹数据则用来算平均移动速度、95 分位离场时间、最大排队时间。下面这段是我常用的一段密度分析代码以“抄作业”的标准给你直接改文件名就能用import pandas as pd df pd.read_csv(density_matrix.csv) # 全局平均密度 avg_density df[Density].mean() print(f平均密度: {avg_density:.2f} 人/m²) # 最大密度及对应时间、网格位置 peak df.loc[df[Density].idxmax()] print(f最大密度: {peak[Density]:.2f} 人/m² TimeStep{peak[TimeStep]} Grid({peak[GridX]}, {peak[GridY]})) # 超过 1.08 人/m²LOS D的时间步占比 threshold 1.08 ratio (df[Density] threshold).mean() print(f超过 {threshold} 人/m² 的时间步占比: {ratio:.1%})注意idxmax()只能找出第一个最大值。如果场景有多个疏散高峰我建议改成按时间步聚合看每个时间步的平均密度再画一条时间曲线。轨迹数据的分析类似主要看离场时间和速度分布import pandas as pd import numpy as np traj pd.read_csv(trajectories.csv) # 只统计移动状态剔除停留 moving traj[traj[Speed] 0.1] avg_speed moving[Speed].mean() print(f平均移动速度: {avg_speed:.2f} m/s) # 每个代理最后出现时间 agent_last_time traj.groupby(AgentID)[Time].max() p95_time np.percentile(agent_last_time, 95) print(f95% 人群离场时间: {p95_time:.1f} s)一个容易忽略的点如果轨迹 CSV 里同一个 AgentID 的最后一条记录并不代表“离场”而是被截断在测量边界外那这个 95 分位就是假的。所以导出轨迹数据时要确认场景边界完整代理全部走到出口之外。3.3 用Matplotlib、Plotly甚至ECharts做汇报级图表有了 DataFrame画图就是顺手的事。密度云图可以用 Matplotlib 的imshow画也可以用 Plotly 做成交互式热力图鼠标移上去能看具体数值。我项目汇报时更倾向 Plotly因为甲方会让我现场放大某个区域看细节交互式图表比静态图片好用得多。下面是一个密度云图的快速绘制代码把密度矩阵变成二维透视表import matplotlib.pyplot as plt pivot df.pivot_table(indexGridY, columnsGridX, valuesDensity, aggfuncmean) pivot pivot.sort_index(ascendingFalse) # 让 Y 轴正向朝上 fig, ax plt.subplots(figsize(10, 7)) im ax.imshow(pivot, cmapjet, originupper) plt.colorbar(im, labelDensity (persons/m²)) ax.set_xlabel(X grid) ax.set_ylabel(Y grid) plt.tight_layout() plt.savefig(density_map.png, dpi200)如果想对接 Web 可视化大屏把结果整理成 JSON 交给 ECharts 很顺手。比如按时间步聚合成平均密度序列前端用折线图或热力图展示。我一般先在 Pandas 里算好再导出 JSONimport json time_series df.groupby(TimeStep)[Density].mean().reset_index() chart_data [ {time: int(row[TimeStep]), avg_density: round(row[Density], 3)} for _, row in time_series.iterrows() ] with open(chart_data.json, w, encodingutf-8) as f: json.dump(chart_data, f, ensure_asciiFalse, indent2)为什么要把 SimWalk 结果搬出来画图因为自带的视图只是一个“快照”没法联动筛选也没法挂到大屏上实时展示多方案对比。外部工具灵活得多颜色、注释、柱状图、雷达图都能做关键是能跟其他专业数据合并形成一份统一风格的交付图纸。4. 一次真实项目的完整结果分析与优化闭环4.1 场景设定与仿真配置拿一个高铁站候车厅疏散模拟项目举例。这个项目的核心要求是把候车厅内 1200 人在突发情况下全部疏散到室外安全区域疏散时间不得高于 6 分钟。候车厅面积大概 40 米乘 60 米四个出口其中两个常用出口宽度 3 米一个应急出口宽度 2.5 米还有一个员工通道不参与疏散。SimWalk 里建模时我按设计图把柱子、座椅、售货亭都建了进去。人群构成按常见比例设置普通成年人 70%老人 15%儿童 10%行动不便者 5%。行走速度在每秒 1.0 到 1.5 米之间随机分布。网格尺寸 0.5 米仿真步长 0.25 秒统计间隔 2 秒。为了降低随机性同一个方案跑了 5 个随机种子取平均结果。这里要说一句随机种子非常重要。SimWalk 的人群生成和路径选择带随机性只跑一遍可能碰上偏激场景。5 个种子都跑完疏散时间的最大值和最小值差距在 10% 以内结果才算稳定。如果一个种子的结果明显异常要回去查模型而不是草率删除。4.2 结果解读疏散时间、瓶颈、密度分布第一次跑完SimWalk 显示平均疏散时间是 384 秒约 6 分 24 秒超标了 24 秒。这就意味着方案不合格必须优化。密度热力图上问题很清楚在西侧安检区到楼梯口的连接通道出现一片红色区域最高密度达到 3.4 人/平方米远超 F 级线。轨迹动画则显示大量人流绕过中央座椅区后同时涌向闸机方向有一个出口承担了 65% 的人流而东侧应急出口只走了 15% 的人。用 Python 导出的轨迹 CSV 进一步算了一下95 分位离场时间是 402 秒最后一个人在第 412 秒才出去。平均移动速度在红色区域降到 0.3 米/秒属于明显停滞。流量数据也印证了楼梯口截面的通过流量在 90 秒到 150 秒之间出现下跌说明拥堵已经反噬了通行能力。这个案例里最大瓶颈不在出口本身而在出口前的汇聚段。很多项目都是这样你把四个出口的宽度数字摆出来每个看起来都够但人流到出口前挤成一团通行能力照样上不去。只看出口宽度不看上游动线是初做疏散分析最容易犯的错。4.3 优化措施与前后对比基于分析我提了三个优化方向。第一把西侧楼梯口到出口之间的隔墙后退 1 米扩大缓冲空间第二在东侧应急出口前增设发光引导标志并通过座椅重排形成一条通往东出口的“引流道”第三把一个主要出口的前置闸机从 6 台增加到 8 台减少闸机处的排队时间。改完模型后重新跑 5 个种子平均疏散时间降到 326 秒约 5 分 26 秒满足 6 分钟要求。95 分位离场时间降到 341 秒。楼梯口处最大密度从 3.4 降到 1.9虽然还是拥挤但不至于停滞。出口流量比例从原来的 65:15 变成 48:32两个出口的利用率均衡了不少。指标优化前优化后判断平均疏散时间秒384326达标95% 离场时间秒402341改善最大密度人/㎡3.41.9大幅改善西侧出口分担率65%48%均衡高风险区数量4 个2 个减少这个案例想说明的是结果分析和可视化不是跑完就结束它们是优化的依据。每一次改动是否有效都得回到同一套结果指标里去看不然就是凭感觉拍脑袋。5. 结果可信度校验与常见排查技巧5.1 先别画图做这四步校验拿到结果不要急着做图先验证可信度。我做项目时固定有四步校验少了哪一步心里都不踏实。第一步是网格无关性检查。把网格分别设成 0.25 米、0.5 米、1 米跑同一个场景对比疏散时间。如果三者的结果差距在 5% 以内说明网格尺寸不是主导因素可以用最省计算量的 0.5 米。如果差距超过了 10%说明你的模型对网格敏感必须用更细的网格。第二步是随机种子检查。同一模型至少跑 3 到 5 个随机种子看疏散时间和最大密度的离散程度。单一结果不能代表真实情况因为在现实里同样条件下每次疏散也会有波动。模拟结果的置信区间比绝对精确值更有参考价值。第三步是流量守恒检查。统计进入场景的总人数、离开场景的总人数和模拟结束时留在场景里的人数三者应该满足进入人数减去离开人数等于系统内人数。如果对不上可能是代理卡在障碍物里没出来或者出口定义有问题。SimWalk 的日志里能看到具体报告别跳过日志直接看图形。第四步是经验公式对照。疏散时间可以用 SFPE 手册里的一些手算公式估个数量级。比如已知楼梯通行能力算出理论通过时间再和 SimWalk 的结果比较。如果模拟比手算快了 3 倍以上多半是模型边界条件设置太宽松。这个对照不需要追求精确但能挡住明显离谱的结果。5.2 常见结果异常及其排查思路实际项目里很容易遇到几个固定异常。我整理了一个速查表方便大家对照。异常现象可能原因排查方法密度图满屏红色网格太细或聚合了全部时间段调粗网格按时间段分别查看疏散时间突然异常大代理被卡在墙角或障碍物附近检查障碍物是否连续、墙线是否闭合轨迹穿墙碰撞模型参数不当或墙线未闭合检查墙体实体增大代理半径导出 CSV 为空测量区域未覆盖、导出范围不对确认测量区与结果图层重新导出动画回放卡顿轨迹显示数量过多只显示 10%-20% 代理关闭阴影两个种子结果差太多随机性过大或模型边界敏感增加种子数查看是否为个别人群路径异常某个出口流量为零代理无法到达该出口检查该出口是否被障碍物遮挡、是否有入口连接每次都仔细看日志。SimWalk 的日志会记录没有到达目的地的代理数量如果这个数量不是零说明模型里有地方让人走不出去。别等到最后发现热力图上有人一直在原地打转那整场仿真基本可以作废。5.3 我常用的几个小技巧最后分享几个私藏技巧。第一个是固定颜色范围这条前面提过但值得再强调。固定颜色标尺后做多方案对比时颜色深浅差异才是“真差异”否则两张图根本不是同一把尺子量出来的。第二个是善用 SimWalk 的区域统计功能。在模型里预先画好“测量多边形”软件会自动统计进出该区域的人数、平均停留时间和最大排队人数。这个功能比我自己写 Python 还准因为它是基于代理的状态数据算的不用我从坐标里猜目的地。第三个是多方案对比时导出数据的时间轴要保持一致。我习惯以模拟开始时间为零点截取前 300 秒数据。如果某个方案只有 280 秒就结束了也要把时间轴补满 300 秒那么对比曲线才公平。补的时间段可以看作是“所有人都已经离场”密度记 0速度不计算。第四个是不要只导一次数据。SimWalk 的结果在每次跑完后都可能变化尤其是我改过模型参数之后。导出数据前确认当前激活的结果集是你想分析的那次而不是上一次的残留结果。我曾经因为没注意结果集被覆盖导出了一份旧的密度数据整个上午白干这是真实踩过的坑。写在最后自己做仿真项目做到现在最大的体会是结果分析和可视化几乎就是仿真本身的价值所在。模型建得再用心参数配得再准最后表达不出来或者表达出来别人看不懂那前面的工作就打了折扣。我始终建议刚开始用 SimWalk 的朋友宁可前期在测量区、导出格式、颜色标尺这些“不起眼”的地方多花半小时也别等到跑完后对着自动生成的彩虹图硬编故事。另外一个实用经验是SimWalk 自带的视图适合自己人看外部工具做出来的图表才适合交付。现在可视化工具的生态很成熟Pandas 加 Plotly或者导出 JSON 接 ECharts都能把仿真数据变成领导、甲方一眼能看懂的汇报材料。把 SimWalk、数据导出、外部可视化这条链路跑通之后后面每个项目都会越来越顺。希望这篇能帮你少走点弯路。