最近分析了一个杭州区域之间OD的数据,需要在杭州行政区底图上绘制OD期望线。主要有两个任务。
1.寻找杭州行政区的shapefile文件,并能被python读取
2.在杭州行政区上,画各个行政区之间的OD期望线
一、查找杭州行政区shapefile文件
step1 : 在这个网址上http://datav.aliyun.com/tools/atlas/index.html#&lat=28.110748760633534&lng=107.8857421875&zoom=4 下载需要城市的json文件,依次在地图上点击 浙江省-杭州市
step2:选择数据版本,城市的行政区这几年可能会有变化(因为我分析的数据基于杭州老的行政区给出的,所以选择的版本为areas_v2)
step3:复制json API地址,并打开。复制json内容,新建txt文档并保存,将txt后缀改为json后缀。
step4:打开这个网址https://mapshaper.org/,并将刚刚创建的json文件拖拽其中,点击import。
step5:显示杭州的行政区划,点击右上角export,保存成shapefile格式。压缩包里的以shp为后缀的文件可以被python读取。
二、python绘制OD期望线
step1:读取底图
# 一、读取底图
# 1.导入需要的包
#geopandas包
import geopandas
#shapely包
from shapely.geometry import Point,Polygon,shape
shp = r'文件路径/XX.shp'
hz = geopandas.GeoDataFrame.from_file(shp,encoding = 'utf-8')
hz.plot()
plot查看行政区读取结果,默认以蓝色底显示,可进行更改,后续绘制OD图时会有。
step2:读取数据(绘制OD图的数据,我的数据保存在excel文档中,用pandas读取)
# 二、读取数据
# 1. 导入包
import pandas as pd
# 2.从excel读取数据
#文件路径
file_path = r'路径\XX.xlsx'
#读取sheet的名字
sheetName = '早高峰'
morning_data = pd.read_excel(file_path,sheet_name=sheetName)
数据格式如下:
step3: 读取坐标文件(我绘制OD图时,按照每个行政区的中心点作为起终点绘制,因为需要在刚刚的OD表上,增加起终点行政区的中心点坐标)
行政区中心点的读取可以从上方第二个网址上查看,选择右边的箭头,放到需要的行政区上,显示该区域的信息,其中有中心点坐标。
# 三、读取坐标文件
#文件路径
file_path = r'文件路径/XX.xlsx'
#读取sheet的名字
sheetName = 'zuobiao'
district = pd.read_excel(file_path,sheet_name=sheetName)
读取数据为:
step4:将坐标表格和OD表格连接,每个OD的行记录都要有起终点行政区的中心点坐标
# 四、连接两个表格
district.columns = ['leave_district','O_x','O_y']
morning_data = pd.merge(morning_data,district,on = ['leave_district'])
district.columns = ['arrive_district','D_x','D_y']
morning_data = pd.merge(morning_data,district,on = ['arrive_district'])
数据变为:
step5:绘制OD期望线
import matplotlib as mpl
import matplotlib.pyplot as plt
fig = plt.figure(1,(10,8),dpi = 250)
ax = plt.subplot(111)
plt.sca(ax)
#绘制行政区划,底图为白色,边框为黑色,宽度为0.5
hz.plot(ax = ax,edgecolor = (0,0,0,1),facecolor = (0,0,0,0),linewidths=0.5)
import matplotlib
#设置colormap的数据
vmax = max(morning_data['cnt'])
#设定一个标准化的工具,设定OD的colormap最大最小值,他的作用是norm(count)就会将count标准化到0-1的范围内
norm = mpl.colors.Normalize(vmin=0,vmax=vmax)
#设定colormap的颜色
cmapname = 'autumn_r'
#cmap是一个获取颜色的工具,cmap(a)会返回颜色,其中a是0-1之间的值
cmap = matplotlib.cm.get_cmap(cmapname)
#绘制OD
for i in range(len(morning_data)):
#设定第i条线的color和linewidth
color_i=cmap(norm(morning_data['cnt'].iloc[i]))
linewidth_i=norm(morning_data['cnt'].iloc[i]) *5
#绘制
plt.plot([morning_data['O_x'].iloc[i],morning_data['D_x'].iloc[i]],
[morning_data['O_y'].iloc[i],morning_data['D_y'].iloc[i]],
color=color_i,linewidth=linewidth_i)
# 绘制假的colorbar,这是因为,我们画的OD是线,没办法直接画出来colorbar
# 所以我们在一个看不见的地方画了一个叫imshow的东西,他的范围是0到vmax
#然后我们再对imshow添加colorbar
plt.imshow([[0,vmax]], cmap=cmap)
#设定colorbar的大小和位置
cax = plt.axes([0.15, 0.4, 0.02, 0.3])
plt.colorbar(cax=cax)
#然后要把镜头调整回到杭州地图那,不然镜头就在imshow那里了
ax.set_xlim(118.2,120.9)
ax.set_ylim(29.0,30.8)
plt.axis('off')
plt.show()
效果图: