公司动态
个人信息可视化实战:数据清洗与ECharts构建三维画像
简介一份面向大数据可视化课程的大作业参考实现覆盖学习生活数据、社会社交关系、地理信息与个人听歌数据等多维度可视化场景。资源包含4个Python脚本及配套数据集可直接运行并替换为自己的数据同时提供HTML动态图表、PNG结果图、说明文档与Excel歌曲数据便于对照理解各图表的生成逻辑。压缩包共22个文件以Python源码、CSV数据、可视化结果图及文本说明为主整体仅1.85MB轻量易用。目前已有4110人学习适合需要快速完成可视化作业或入门数据可视化的同学借鉴。代码结构清晰、易懂易改支持按需调整颜色与展示效果其中地理信息部分附有专项说明可帮助修改淄博市地图等可视化结果。 如果有人问《大数据可视化》这门课的期末大作业里最容易被低估的选题是什么我一定提名“个人信息可视化展示”。刚看到题目时多数人的第一反应是这不就是把成绩柱状图、朋友圈词云、旅游地图贴在带网格的展板上吗真正动手以后才发现这门课虽然挂着“可视化”三个字但大作业里最折磨人的部分全在数据获取、数据清洗和叙事组织上。学习生活数据、社交关系、地理信息和其他个人信息这四块内容如果各自为战出来的作品就是四张毫无关联的图如果能统合成一套完整的数据资产展示方案它就能变成一份让答辩老师眼前一亮的三维个人画像。这篇文章我会从题目的拆解逻辑讲起完整记录我自己的做法——数据从哪来、图怎么选型、有哪些坑以及如何在期末汇报里把四个板块讲成一个完整故事。不论你是正打算选这门课还是赶在DDL前找参考应该都能从中找到可以直接搬运的方案。1. 拿到题目先别碰代码把四类数据当成四种叙事来规划我见过太多同学拿到题目后的第一步是打开抓包工具准备把各种App的数据都搬回本地。方向没错但顺序是错的。个人信息可视化作业的第一阶段不是采集数据而是想清楚四个板块各自的叙事任务学习生活数据回答“时间花在哪”社交关系回答“身边的人如何连接”地理信息回答“我去过哪里”其他个人信息则用来回答“我是谁”。这四个问题必须各有各的图表主线否则最后做出来的首页就是一锅乱炖老师根本不知道你想表达什么。1.1 先确定图表类型要匹配数据特征而不是反过来我个人比较推荐在开始写代码之前先画一张“数据-图表映射表”把每一类数据要回答的问题、适合的图形和分析目标列清楚。数据板块要回答的问题推荐图表核心分析目标学习数据成绩如何波动折线图、箱线图、平行坐标成绩变化趋势、学科结构生活数据时间花在哪日历热力图、堆叠条形图作息规律、时间分配社交数据人际关系如何连接力导向图、弦图、玫瑰图关系强度、群体结构地理数据去过哪里、停留多久地图散点、热力图、航线图到访频次、活动范围其他数据我是谁词云、雷达图、桑基图个人画像、兴趣偏好这个映射关系最好在动手前就写进设计文档。别小看这一步它决定了你后面所有代码的组织方式。如果一开始就把某个网络的社交数据硬塞进柱状图后面会花双倍时间返工。1.2 四个板块的数据可得性预先评估不同板块的数据来源和获取难度差异很大我用一张表格做了预备评估也建议你照着盘点一遍学习数据教务系统成绩单、课程表、番茄钟记录获取难度低注意不要直接展示学号。生活数据记账App导出、手机健康、屏幕使用时间难度低到中避免暴露具体家庭住址。社交数据通讯录vCard导出、聊天记录统计、平台数据导出难度中只保留聚合统计值。地理数据相册照片EXIF、出行App时间线、地图收藏难度中家庭地址要做模糊化。做完这张表你基本能预估出哪些板块能快速出成果哪些板块需要提前去申请导出权限或者找替代数据。对于课程作业来说最忌讳的是把自己卡在某个数据处理环节上整整一周导致后期图表制作时间被严重压缩。1.3 技术栈选择为什么我坚持用Python加ECharts技术选型上我的固定组合是Python pandas做清洗统计图表渲染全部交给ECharts。如果你不想写前端页面可以用pyecharts这个库它把ECharts封装成Python接口操作起来顺手得多。为什么不直接上D3因为课程作业周期短D3的复杂度远高于ECharts写一个力导向图ECharts半小时能搞定D3你光调库就要研究半天。地图部分也不建议一开始就引入高德或百度地图SDK用ECharts自带的Geo组件加载GeoJSON就够了省去申请Key的麻烦还方便离线使用。2. 学习与生活数据从成绩单、番茄钟里挖出的时间账本学习生活数据是整个大作业的基本盘。老师的预期是通过这部分看到你的学习状态和生活习惯的变化如果你只是把每科成绩丢进柱状图里那最多算完成基础要求。这部分我用了大概一周时间绝大部分不是花在画图而是花在把三四年间格式乱七八糟的表格统一成一套标准数据上。2.1 成绩数据怎么画才不像“应付作业”成绩部分我做的是三个维度学期绩点趋势、课程类别构成、成绩与学习行为的关联。教务系统下载的成绩单通常是Excel表字段不统一有的表叫“课程性质”有的叫“课程类型”还有的用“优秀”“良好”这类等级表示法。我先用pandas统一字段名再用正则把等级制转成数值比如优秀按95分折算良好按85分折算。折算规则不是随便定的需要写进报告里体现你对数据口径的思考。下面这段代码是当时处理成绩数据的关键逻辑import pandas as pd df pd.read_excel(grades.xlsx) # 等级制折算这里根据学校评分标准设定 df[score] df[score].map({优秀: 95, 良好: 85, 通过: 75}) df[semester] df[semester].astype(str).str.replace(学年-, 20) # 加权平均分 avg df.groupby(semester).apply( lambda x: (x[score] * x[credit]).sum() / x[credit].sum() )把处理后的学期加权均分画成折线图后我还叠加了一个“各学期专业课占比”的堆叠柱状图。这样老师一眼就能看出什么时候你在密集上专业课什么时候绩点随选修课比例上升而变化信息密度远超单张成绩图。如果你还想更进一步可以把“每门课程的投入时长”和“该课程得分”放到双Y轴折线图中观察相关性这个视角答辩时会很加分。2.2 生活数据的时间开销小时桶聚合与热力图生活数据最好的切入点是“时间都去哪了”。我把手机屏幕使用时间、番茄钟专注记录、课程表合并成一张以分钟为单位的明细表然后做了一个关键转换把时间戳对齐到小时桶统计每个小时内的记录数。为什么不用分钟级因为个人数据里天然存在大量噪音比如解锁一次手机只用了20秒这并不能说明任何作息规律小时级别反而能突显出“上午课程密集、晚间刷视频”这类稳定行为模式。处理完后我用日历热力图展示一个月的专注时长分布用24小时堆叠条形图展示一天内课程、自习、娱乐的时间占比。两者组合起来既能看月度趋势又能看日内规律答辩时解释起来非常直观。生活数据里睡眠和运动也很适合做但一定注意数据的时间跨度要够长只有一两周的数据画折线图会非常难看。2.3 清洗过程最容易失手的三件事清洗学习生活数据时最常见的坑有三个我建议记录下来时间格式统一不同App导出的时间格式千奇百怪有“2024/03/01”也有“2024-03-01”pandas读进来全变成字符串必须先统一再排序。空值处理不能一刀切很多睡眠App晚上没记录不代表你没睡而是传感器没检测到。直接drop行会把数据烧得更稀疏我采取的是按0补但图例上注明“0代表未检测到”保证口径透明。隐私字段剔除成绩表里往往带着学号、身份证号等无关字段清洗阶段直接删掉避免答辩展示时不小心暴露也省得后续脱敏返工。3. 社交关系可视化通讯录与聊天记录里藏着的关系图谱社交关系是很多同学最头疼的板块因为数据不好拿就算拿到也容易画成乱麻。我当时用的组合是手机通讯录导出vCard文件结合聊天软件里导出的消息统计生成一套“联系人-连接强度”的数据结构。这里必须强调一条红线不要为了作业去爬取任何人的聊天原文、手机号、头像等敏感内容只保留聚合后的统计信息比如互动天数、消息条数。这个原则会让你在答辩时从容很多。3.1 如何把通讯录和聊天记录整理成可计算的图结构通讯录vCard文件可以通过Python的vobject库解析拿到姓名、电话、分组等信息。聊天记录里的消息统计需要从App导出通常只能得到一系列聚合数值。我把两类数据合并后定义成这样的图数据格式{ nodes: [ { name: 同学A, category: 同学, value: 35 }, { name: 家人B, category: 家人, value: 58 } ], links: [ { source: 我, target: 同学A, value: 1200 } ] }这里节点value表示互动天数链接value表示消息条数。数据本身就是图结构直接喂给ECharts的graph类型设置layout为force基础关系图就出来了。关键是让数据符合直觉连线越粗消息越多节点越大互动越频繁。这是社交关系可视化最核心的编码逻辑。3.2 力导向图不要布局全量数据要布局有效关系第一次渲染时我把所有联系人都丢进图里结果整个页面变成一团毛线。后来总结了三板斧过滤、聚合、聚类。过滤是把聊天记录少于10条的边全部去掉这些弱连接对整体结构贡献极小却会让布局崩溃。聚合是把低频联系人合并成一个“其他联系人”节点保留整体占比。聚类则是按通讯录分组给节点上同色并让同组节点在力导向布局里的初始位置靠在一起这样一眼就能看出社交群体的边界。做完这三步图才有结构感老师看图时能立刻理解你的社交圈构成。3.3 交互上最值得加的两个功能社交图的交互层面我加了两处设计。第一是hover高亮邻居节点利用ECharts的emphasis.focus设置为adjacency鼠标悬停某个节点时只高亮其直接连接的节点和边这样可以极大降低视觉干扰。第二是增加一个按周滚动的timeline配合消息量曲线看社交活跃度的时间变化这能证明你不只是会画图还会用时间维度辅助分析。这两项功能实现成本不高但能明显拉高作品的完成度。4. 地理信息可视化照片EXIF和出行记录拼出的空间轨迹地理信息板块是视觉冲击力最强、也最容易翻车的部分。地图类图表只要坐标不准或者底图加载失败整页质感会一起崩掉。我第一次做的时候就是没处理好离线加载问题答辩演示中途地图区域一片白非常尴尬。4.1 两类经纬度数据的获取方式个人经纬度数据可以分成两类。一类是长期静态点比如家、学校、常去的教室和食堂我通过地图收藏和外卖收货地址反查再用地理编码API把文字地址转成经纬度定位精度到几百米就够用。另一类是动态轨迹最优解是读取手机相册照片的EXIF信息。相册里的照片几乎都带GPS坐标把一段时间内所有照片的位置提取出来按日期排序就能还原你实际到访过的地点序列。这段提取代码是所有地理数据处理里最实用的一段from PIL import Image from PIL.ExifTags import TAGS, GPSTAGS def get_gps_from_image(img_path): img Image.open(img_path) exif img.getexif() gps_info {} for tag_id, value in exif.items(): tag_name TAGS.get(tag_id, tag_id) if tag_name GPSInfo: for gps_tag, gps_value in value.items(): gps_info[GPSTAGS.get(gps_tag, gps_tag)] gps_value if GPSLatitude in gps_info and GPSLongitude in gps_info: lat convert_to_decimal(gps_info[GPSLatitude], gps_info[GPSLatitudeRef]) lon convert_to_decimal(gps_info[GPSLongitude], gps_info[GPSLongitudeRef]) return lat, lon return None这里convert_to_decimal是把度分秒格式转成十进制小数这是所有地图可视化工具最需要的数据格式。4.2 地图底图的离线化与图层叠加呈现方式上我用ECharts的Geo组件加载一份本地GeoJSON作为底图再叠加一个scatter图层让散点大小对应该城市到访次数颜色深浅对应累计停留时长。接着加一层城市间连线把“家-学校-旅行目的地”串成带箭头的曲线配合动画效果整个页面像一张迷你航线图。这里最要命的一点就是离线化pyecharts默认加载部分地图资源需要访问CDN一旦答辩现场网络不稳地图区域直接白屏。我的做法是把所需的GeoJSON文件全部下载到项目本地index.html里通过相对路径引入并且答辩前一天用手机热点和断网两种模式各跑一遍。4.3 单点详情层从坐标到业务语义地图上每个点如果只能显示经纬度这个板块就只做到了一半。我写了一个自定义格式化函数把一个城市名映射到停留天数、首末到访日期、照片数量用户点击散点后弹窗显示这些聚合信息。这一步的意义在于你成功把原始坐标数据加工成了可解释的业务语义这正是“数据可视化”和“画图”之间的关键区别。5. 其他个人信息把杂项数据做成一页个人画像其他个人信息是整份作业的开放题没有标准答案做得好反而能成为最大亮点。我当时选了三组数据年度收支、书影音记录、健康指标。选它们的原因很简单数据源稳定且能分别代表“钱怎么花、兴趣在哪、身体状态如何”凑在一起就是一份数字化个人速写。5.1 三组数据的图表组合拳收支数据我用桑基图展示收入流到餐饮、交通、购物、学习等具体类目的去向比普普通通的饼图更能展现资金流动的结构。书影音记录用词云加类型条形图词云展示高频作者和片名关键词条形图展示年度阅读量分布。健康数据用雷达图把几个月内的平均睡眠时长、运动时长、静息心率放在同一张图上能直观看出状态起伏。这三张图单独看都不复杂但放到同一页时要特别小心它们之间的信息层级。我的经验是不要超过四个图表否则页面会变得很挤反而弱化了个人画像的核心感。5.2 页面架构让零散数据变成完整故事为了让这些杂项数据不显得拼凑我建议整份Dashboard的页面结构从上往下这样排第一屏放个人基本信息标签包括专业年级、MBTI、每日平均屏幕时间等下面紧跟一句话数据画像总结第二屏进入学习生活第三屏是社交关系第四屏是地理轨迹最后再回到其他生活数据收尾。这样从头到尾的叙事是顺着数据流走的评审每往下滚动一屏都能获得新维度的信息而不是面对一堆并列的图。这里有个小细节个人信息标签的个数控制在8到10个不要贪多。你展示的是可视化思维不是把所有隐私全公开。标签数据本身量很小直接在前端用JS对象维护就够了没必要动用后端。6. 从踩坑到答辩这份大作业落地的完整经验复盘最后分享几个我在整个过程中踩过的坑以及答辩前的准备思路这些经验也许比前面的技术方案更值得你保留。6.1 三个最让我翻车的技术问题第一个坑是数据时间跨度过短导致图表断档。我一开始选了一周的运动数据来画折线图结果图几乎就是一条直线加几个离群点毫无说服力。后来把数据扩展为三个月并且用滚动窗口平均做了平滑图表才有趋势起伏。做个人数据可视化一定要保证时间跨度足以形成稳定的统计规律两三个月的单数据确实太单薄。第二个坑是地图组件离线失败。起初我依赖在线地图资源答辩彩排时网络一波动整个地图模块就变成空白吓得我当场冒汗。解决方式已在前文提到将所有底图JSON本地化在无网环境下完整跑通。第三个坑是图表文字和标签过小。在1080P投影仪下代码里的默认字号经常看不清。我最后做了全局调整把label字号加大不必要的图例一律关掉保证每屏核心信息被一眼抓住。6.2 报告和答辩现场的关键细节报告里一定要写清楚三件事数据来源和采集时间、数据清洗流程、每张图的选型依据。特别是第三点不能只写“我用了折线图”要写“因为成绩是时间序列折线图最符合趋势呈现因为好友关系是网络结构力导向图能保留拓扑信息”。这句表述虽短却是很多作品缺失的高分关键。答辩现场我习惯准备一个30秒项目导览加一个3分钟完整讲解。项目导览直接展示首页Dashboard用一句话说明叙事逻辑完整讲解按学习、社交、地理、其他四个板块逐个展开每块40秒左右。如果老师问到数据隐私问题就回答“所有展示均经过脱敏处理仅保留统计层级数据”这句话能消除大部分疑虑。正式答辩前一定记得在断网环境完整跑一遍项目这是最低成本的保命操作。本文还有配套的精品资源点击获取