目录
学习目标
- 数据可视化基础;
- 出租车轨迹可视化;
- 出租车热度可视化;
数据可视化
数据可视化(Data Visualization)是聚焦数据表现形式的领域,如何将信息进行抽象、对比和展示的方法。数据可视化在不断发展,可供使用的工具和展示形式在不断演变。与数据科学的其他方向相比(机器学习和数据挖掘),可视化涵盖的技术方法更多,形式更加多样。
下图,未来美国的人口统计数据(不同年龄阶段)
下图,电影对白(按性别划分)
数据可视化根据用途可以划分为:
- 数据统计展示;
- 数据分布展示;
- 数据对比展示;
数据可视化在机器学习&深度学习中应用广泛:
- 特征相关性热力图;
- 特征分布趋势图;
- 梯度可视化图;
- 特征重要性直方图;
在交通领域,数据可视化同样用途广泛:
- 通过可视化可以找到热门的区域,定位到拥堵区域;
- 通过可视化可以找到热门的线路,定位拥堵线路;
- 通过可视化可以找到交通的流量;
无一例外,现有地图大数据报告都使用可视化的方式进行呈现:
- 百度交通大数据报告:https://jiaotong.baidu.com/reports/
- 滴滴交通大数据报告:https://sts.didiglobal.com/
- 高德交通大数据报告:https://report.amap.com/diagnosis/index.do
- 腾讯地图大数据:https://heat.qq.com/
常规可视化
可视化是每一位同学必备的技能,同时也是需要反复练习的技能,是必备的技能。学习可视化,可以通过如下的流程完成:
- 学习可视化的组成元素;
- 学习可视化的常见图像案例;
- 学习可视化库的使用;
如上图在绘制一张图的过程中,有较多的细节需要注意,上图来源为matplotlib。一张图包含的具体的组成元素如下:
- 坐标轴、坐标轴标题;
- 图表标题、数据标签;
- 误差线、网格线;
- 图例等;
上述的每个元素搭配起来就是整张图,看起来是不是非常简单?所以可视化并不是一件很难的事情,只需要注意到细节就肯定可以绘制得到美观的图。但可视化的内容实在是太多了,我们推荐的学习路线如下:
- 步骤1:学习有哪些可视化方法;
- 步骤2:选择一个库进行具体可视化;
可视化图表类型
- 饼图(Pie Chart)或称饼状图,是一个划分为几个扇形的圆形统计图表。在饼图中,每个扇形的弧长(以及圆心角和面积)大小,表示该种类占总体的比例,且这些扇形合在一起刚好是一个完全的圆形。
- 散点图(Scatter Plot)是在笛卡尔座标上放置一系列的数据点,用来显示两个变量的数值(每个轴上显示一个变量),并检测两个变量之间的关系或相关性是否存在。
- 条形图(Bar Chart)采用水平或垂直条形(柱形图)来比较不同类别的离散数值。图表其中一条轴代表要比较的具体类别,另一条则用作离散数值的标尺。
数据可视化图表类型,实在是太多了(至少几十种),而且每种图的元素、特点和计算逻辑都不太一样,由于篇幅原因我们就不展开讲。当然不是要求大家对每一种图都熟悉,是希望大家知道有这些图的存在,如果之后画图可以找一种更加有效的图进行展示。非常推荐大家阅读下面的两个可视化介绍网站:
- 箱形图(又称为「盒须图」或「箱线图」)能方便显示数字数据组的四分位数。
可以从箱形图得出的观察结果:
- 关键数值,例如平均值、中位数和上下四分位数等;
- 任何异常值(以及它们的数值);
- 数据分布是否对称;
- 数据分组有多紧密;
- 数据分布是否出现偏斜(如果是,往什么方向偏斜);
地图可视化
地图可视化方法如下:
- 点示地图 (Dot Map) 在地理区域上放置相等大小的圆点,旨在检测该地域上的空间布局或数据分布。
- 气泡地图指定地理区域上方会显示圆形图案,圆形面积与其在数据集中的数值会成正比。
- 连接地图 (Connection Map) 即是用直线或曲线连接地图上不同地点的一种图表。
- 流向地图 (Flow Map) 在地图上显示信息或物体从一个位置到另一个位置的移动及其数量,通常用来显示人物、动物和产品的迁移数据。
- 地区分布图通常用来显示不同地理分区或区域(不同颜色或图案)与数据变量之间的关系,并把所显示位置的数值变化或模式进行可视化处理。
赛题可视化
基于上面的可视化方法,我们可以使用可视化方法完成基础的数据可视化,下面代码以将以巡游车GPStaxiGps20190531.csv
为案例进行数据统计。
- 24小时巡游车统计数量
taxigps2019.groupby(['GPS_TIME_hour'])['CARNO'].nunique().plot()
plt.ylabel('Car Count')
- 24小时巡游车平均GPS速度
taxigps2019['GPS_SPEED'] = np.clip(0, 150, taxigps2019['GPS_SPEED'])
taxigps2019.groupby(['GPS_TIME_hour'])['GPS_SPEED'].mean().plot()
taxigps2019[taxigps2019['GPS_SPEED'] != 0].groupby(['GPS_TIME_hour'])['GPS_SPEED'].mean().plot()
plt.legend(['Mean GPS Speed, contain 0', 'Mean GPS Speed, not contain 0'])
- 24小时巡游车平均运营车辆
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
df = taxigps2019[taxigps2019['OPERATING_STATUS'] == 1]
df.groupby(['GPS_TIME_hour'])['CARNO'].nunique().plot()
df = taxigps2019[taxigps2019['OPERATING_STATUS'] == 8]
df.groupby(['GPS_TIME_hour'])['CARNO'].nunique().plot()
plt.legend(['STATUS 1', 'STATUS 8'])
- 某个时间巡游车位置分布
from folium import plugins
from folium.plugins import HeatMap
map_hooray = folium.Map(location=[24.482426, 118.157606], zoom_start=14)
HeatMap(taxigps2019[['LATITUDE', 'LONGITUDE']].iloc[:1000].values).add_to(map_hooray)
map_hooray
- 某个巡游车具体的路线
import folium
# Create the map and add the line
m = folium.Map(location=[24.482426, 118.157606], zoom_start=12)
my_PolyLine=folium.PolyLine(locations=taxigps2019[taxigps2019['CARNO'] == '0006d282be70d06881a7513b69fcaa60'][['LATITUDE', 'LONGITUDE']].iloc[:50].values,weight=5)
m.add_children(my_PolyLine)
学习资源
任务
- 可视化巡游车
20190531
-20190609
期间早上9点的平均速度变化
# 加载数据集
taxiGps = list()
for i in ['20190531', '20190601', '20190602', '20190603', '20190604', '20190605', '20190606', '20190607', '20190608', '20190609']:
df = pd.read_csv(
f'data/taxiGps{i}.csv',
dtype = {
'OPERATING_STATUS': np.uint8,
'GPS_SPEED': np.float32,
'DRIVING_DIRECTION': np.uint16,
'LONGITUDE': np.float32,
'LATITUDE': np.float32,
}
)
taxiGps.append(df)
# 将GPS_TIME的数据类型转换为datetime
for df in taxiGps:
df['GPS_TIME'] = pd.to_datetime(df['GPS_TIME'])
# 筛选出每天9点的数据
GPS_TIME_HOUR_9 = list()
for df in taxiGps:
GPS_TIME_HOUR_9.append(df.set_index('GPS_TIME'))
dates = ['2019-05-31 09', '2019-06-01 09', '2019-06-02 09', '2019-06-03 09', '2019-06-04 09', '2019-06-05 09', '2019-06-06 09', '2019-06-07 09', '2019-06-08 09', '2019-06-09 09']
for i, date in zip(range(10), dates):
GPS_TIME_HOUR_9[i] = GPS_TIME_HOUR_9[i][date]
# 统计每天的平均速度
mean_speed_contain_0 = list()
mean_speed_not_contain_0 = list()
for i in range(10):
mean_speed_contain_0.append(GPS_TIME_HOUR_9[i]['GPS_SPEED'].mean())
mean_speed_not_contain_0.append(GPS_TIME_HOUR_9[i].loc[GPS_TIME_HOUR_9[i]['GPS_SPEED'] != 0]['GPS_SPEED'].mean())
# 画图
x = ['0531', '0601', '0602', '0603', '0604', '0605', '0606', '0607', '0608', '0609']
fig, ax = plt.subplots()
# Using set_dashes() to modify dashing of an existing line
line1, = ax.plot(x, mean_speed_contain_0, label='Mean GPS Speed, contain 0')
line1.set_dashes([2, 2, 10, 2]) # 2pt line, 2pt break, 10pt line, 2pt break
# Using plot(..., dashes=...) to set the dashing when creating a line
line2, = ax.plot(x, mean_speed_not_contain_0, dashes=[6, 2], label='Mean GPS Speed, not contain 0')
ax.legend()
plt.show()
- 可视化巡游车
20190531
-20190609
期间巡游车运营时间变化
# 统计每天巡游车运营时间
mean_time = list()
for i in range(10):
taxiGps[i]['GPS_TIME_H_M'] = taxiGps[i].GPS_TIME.map(lambda x: ':'.join(str(x).split()[1].split(':')[:2]))
mean_time.append(taxiGps[i].groupby(['CARNO'])['GPS_TIME_H_M'].nunique().mean())
# 画图
x = ['0531', '0601', '0602', '0603', '0604', '0605', '0606', '0607', '0608', '0609']
fig, ax = plt.subplots()
# Using set_dashes() to modify dashing of an existing line
line1, = ax.plot(x, mean_time, label='Mean Run Time')
line1.set_dashes([2, 2, 10, 2]) # 2pt line, 2pt break, 10pt line, 2pt break
ax.legend()
plt.show()