资讯动态

基于Python的城市轨道交通数据可视化:从数据清洗到ECharts交互图表

发布时间:2026/10/12 19:48:41 来源:尧图企业网站定制
简介这份资源是面向高校学生与Python初学者的数据可视化课程设计参考包以中国城市轨道交通为主题适合用作期末大作业、实验实践或课程设计选题。项目通过多线程爬虫采集高德地图的轨道交通数据再借助Python可视化库完成城市分布、线路站点数量、换乘站点统计、地铁站命名用字词云等分析并配套GUI界面实现数据库与文件信息查询覆盖爬虫、数据分析、界面开发与数据库连接等环节。压缩包共35个文件约3.44MB包含3个Python源码文件、20张png图表、4个html交互页面、2个csv数据文件、1个db数据库及使用说明txt结构清晰便于按模块阅读与复现。目前已有395人学习下载读者可参考完整分析流程、图表实现方式与项目组织思路快速搭建自己的可视化作业框架。1. 从一份期末大作业说起城市轨道交通数据可视化到底在做什么每年期末季总有人拿着一份「基于Python的中国城市轨道交通数据可视化分析源码」来找我问的无非两件事这东西能不能跑起来以及跑起来之后能不能改。先说结论——这类项目本质上是一条从原始运营数据到可交互图表的完整链路核心工作是把线路、站点、客流、换乘这些结构化字段变成折线图、热力图、网络拓扑图让人一眼看出哪条线最挤、哪个站换乘压力最大。它适合三类人正在赶课程设计的学生、想练手 Python 数据分析的入门者、以及需要快速搭一个可视化 Demo 的开发者。热搜里 python 入门、数据可视化、echarts 数据可视化这几个词反复出现说明大家真正卡住的不是「要不要做」而是「数据从哪来、用什么画、怎么让图不丑」。这一章先把整件事的边界划清楚后面几章再一步步落地。2. 数据从哪来、长什么样轨道交通数据集的字段拆解与清洗2.1 常见数据来源与字段结构做城市轨道交通可视化第一步永远不是写代码而是搞清楚手里有什么数据。常见的来源有三类一是各城市地铁官网或开放数据平台公布的线路站点表通常是 CSV 或 Excel二是课程项目里自带的模拟数据集字段往往已经整理好三是通过公开 API 或爬虫获取的客流统计数据。不管哪种来源核心字段基本跑不出下面这张表字段名含义典型类型是否必填line_name线路名称字符串是station_name站点名称字符串是station_order站点在线路中的序号整数是longitude经度浮点数是latitude纬度浮点数是passenger_flow日客流量整数否transfer_lines可换乘线路字符串否open_date开通日期日期否拿到数据后第一件事是看缺失值和重复值。站点名称重复是最常见的坑比如「人民广场」可能同时出现在 1 号线和 2 号线的记录里如果不加线路前缀去重后面画网络图时节点会合并换乘关系就全乱了。2.2 用 pandas 做清洗的最小代码import pandas as pd # 读取原始数据注意编码国内 Excel 导出的 CSV 常见 gbk df pd.read_csv(metro_data.csv, encodinggbk) # 1. 去掉完全重复的行 df df.drop_duplicates() # 2. 站点名称去空格避免「人民广场 」和「人民广场」被当成两个站 df[station_name] df[station_name].str.strip() # 3. 构造唯一站点标识线路名 站点名 df[station_id] df[line_name] _ df[station_name] # 4. 检查经纬度缺失缺失的站点直接标记出来人工确认 missing_coord df[df[longitude].isna() | df[latitude].isna()] print(f经纬度缺失站点数{len(missing_coord)}) print(missing_coord[[line_name, station_name]])这段代码的逻辑很直白先去重再规范化站点名然后拼出一个全局唯一的 station_id。参数上唯一需要注意的是encoding国内很多数据集是 gbk 或 gb2312用 utf-8 读会直接报 UnicodeDecodeError。如果报错换成encodinggbk或encodingutf-8-sig试一次基本能解决。经纬度缺失的站点不要直接 drop先打印出来因为有些城市的数据里部分站点确实没有坐标需要手动补或者从地图服务查。2.3 线路顺序与换乘关系的整理站点顺序字段 station_order 决定了折线图怎么连。如果这个字段缺失就得靠经纬度去推算但推算出来的顺序在环线或支线上经常出错。我的做法是优先用原始数据里的 order没有的话按线路分组后手动排一遍宁可花十分钟核对也不要让程序猜。换乘关系则要从 transfer_lines 字段拆开一个站可能对应多条线路拆完之后可以生成一个「站点-线路」的边列表后面画网络图直接用它。# 拆分换乘线路生成边列表 edges [] for _, row in df.iterrows(): if pd.notna(row[transfer_lines]): for t_line in str(row[transfer_lines]).split(;): edges.append({ source: row[station_id], target: t_line.strip() _ row[station_name] }) edge_df pd.DataFrame(edges) print(edge_df.head())这里用分号拆分是因为多数数据集用分号或逗号分隔换乘线路具体看你的数据。拆完之后 edge_df 就是网络图的输入source 和 target 都是 station_id 格式保证节点能对上。3. 用 Python 画图还是上 ECharts可视化方案选型与最小可跑示例3.1 matplotlib、pyecharts、ECharts 三者的取舍很多人一上来就问用哪个库其实答案取决于你的输出场景。如果只是课程报告里放几张静态图matplotlib 足够学习成本最低如果要交互、要能缩放拖拽、要放进网页pyecharts 是 Python 侧最顺手的选择它底层就是 ECharts生成的 HTML 可以直接打开如果前端已经有一套 Vue 或 React 项目那就直接上 EChartsPython 只负责出 JSON 数据。热搜里 echarts 数据可视化和企业级数据可视化这两个词热度很高说明大家最终都绕不开交互式图表所以这一章重点讲 pyecharts 和 ECharts 的落地路径。选型上还有一个容易被忽略的点数据量。站点数量在几百以内三种方案都没压力如果要做全国几十个城市、上万个站点的对比matplotlib 渲染会明显变慢pyecharts 的 HTML 文件也会大到浏览器卡顿这时候要考虑数据分片或者用 ECharts 的增量渲染。3.2 用 pyecharts 画线路客流折线图from pyecharts.charts import Line from pyecharts import options as opts # 假设已经按线路和站点顺序排好 line_data df[df[line_name] 1号线].sort_values(station_order) x_data line_data[station_name].tolist() y_data line_data[passenger_flow].fillna(0).tolist() line ( Line() .add_xaxis(x_data) .add_yaxis(1号线日客流, y_data, is_smoothTrue) .set_global_opts( title_optsopts.TitleOpts(title1号线各站客流分布), xaxis_optsopts.AxisOpts(name站点, axislabel_optsopts.LabelOpts(rotate45)), yaxis_optsopts.AxisOpts(name客流量), datazoom_optsopts.DataZoomOpts(range_start0, range_end50), ) ) line.render(line1_flow.html)这段代码的关键参数有三个is_smoothTrue让折线平滑视觉上更舒服但数据波动大时反而失真客流数据我一般不开axislabel_optsopts.LabelOpts(rotate45)解决横坐标站点名太密的问题热搜里 python 画图横坐标太密集说的就是这个datazoom_opts加上缩放条站点多了之后用户可以自己拖。渲染出来的 HTML 直接用浏览器打开就能交互不需要起服务。3.3 换乘网络图与地理散点图的实现要点网络图用 pyecharts 的 Graph 类节点是站点边是换乘关系。地理散点图则需要 BMap 或 Geo但 BMap 依赖在线地图服务离线环境用不了这时候可以退而求其次用 Geo 配合经纬度画散点底图用内置的中国地图。from pyecharts.charts import Geo from pyecharts.globals import ChartType geo ( Geo() .add_schema(maptypechina) .add( 站点分布, [(北京, 100), (上海, 80), (广州, 60)], # 这里换成你的城市和客流量 type_ChartType.EFFECT_SCATTER, ) .set_series_opts(label_optsopts.LabelOpts(is_showFalse)) ) geo.render(station_geo.html)注意 Geo 的 add_schema 里 maptype 写「china」是全国地图要画单个城市得用城市名但内置地图只到省级和部分市级更细的底图需要自己准备 GeoJSON。这一步是很多人翻车的地方——以为 pyecharts 什么地图都有结果发现自己的城市不在内置列表里。解决办法是去公开的 GeoJSON 数据源下载对应城市的边界文件用add_geo_json注册进去。4. 避坑与排查轨道交通可视化里最容易翻车的五个地方4.1 中文乱码从 CSV 读取到 HTML 渲染现象图表标题和站点名显示成方块或问号。原因CSV 编码和 Python 默认编码不一致或者 HTML 文件没有声明 UTF-8。解决读文件时显式指定 encodingpyecharts 生成的 HTML 默认已经带 meta charset如果还乱码检查你的数据在写入前是否被错误解码。我一般会在读取后立刻print(df.head())看一眼乱码当场就能发现别等到画完图才回头查。4.2 站点顺序错乱导致折线图来回折现象折线图上下乱跳完全看不出趋势。原因station_order 字段没有排序或者排序后索引没重置画图时按原始索引取数。解决sort_values(station_order)之后加.reset_index(dropTrue)确保 x 轴和 y 轴一一对应。这个坑我踩过不止一次尤其是从 Excel 读进来的数据行顺序看着对实际 order 列是乱的。4.3 换乘站被重复计算客流现象总客流量比官方公布的高出一大截。原因换乘站同时属于多条线路按线路汇总时被加了多次。解决做全网客流统计时先按 station_id 去重再求和做线路客流时保留重复因为换乘站的客流确实要分摊到各线路。这两种口径不能混用报告里要写清楚用的是哪种。4.4 pyecharts 版本不兼容导致 API 报错现象照着教程写的代码报TypeError或AttributeError。原因pyecharts 0.5 和 1.x 的 API 差异很大网上很多教程还是旧版写法。解决先pip show pyecharts看版本1.x 用opts模块配置0.5 用**kwargs。如果不想折腾直接锁定 1.9 以上的版本本文代码都按 1.x 写。4.5 生成的 HTML 文件过大打不开现象浏览器打开 HTML 卡死或白屏。原因数据点太多或者把原始数据全塞进了图表配置。解决只传绘图需要的字段不要整个 DataFrame 转 list站点超过两千个时考虑按线路拆分多个 HTML或者改用 ECharts 配合后端接口按需加载。5. 从能跑到好用三个让图表更专业的细节技巧第一个技巧是给数据加一层「归一化」。不同线路的客流量量级可能差十倍直接画在同一张图上小的那条线几乎看不见。我的做法是对客流量做 min-max 归一化或者用双 Y 轴把量级差异大的指标分开。归一化代码就三行flow df[passenger_flow] df[flow_norm] (flow - flow.min()) / (flow.max() - flow.min())第二个技巧是颜色映射要跟数据含义挂钩。客流热力图用红黄渐变是直觉但换乘线路数量用同一套色系就会误导人。我一般给客流量用暖色系给换乘数用冷色系图例上写清楚单位别让人猜。第三个技巧是导出前检查交互。pyecharts 生成的图在本地打开正常不代表嵌入网页后正常尤其是 datazoom 和 tooltip 在移动端可能失效。我的习惯是生成 HTML 后用手机浏览器也开一次确认缩放和点击都没问题再交付。最后说一个验证方法拿官方公布的某条线路日均客流去对你自己算出来的总数误差在 5% 以内说明清洗和汇总逻辑没问题超过 10% 就得回头查换乘站去重和缺失值填充。这个对账步骤很多人跳过结果答辩时被问一句「你这数据准吗」就答不上来。我做这类项目最大的教训是别一上来就追求图表炫酷先把数据字段对齐、口径统一图丑一点没关系数据错了整个分析就是空中楼阁。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑