地图省界线什么样_数据可视化技巧(一):怎样用Python绘制简单数据地图
严格绘制数据地图并不是一件简单的事情。专业的做法应当使用 GIS(地理信息系统)的专业软件。在这些软件中需要设置底图、投影方式、坐标、高程等等。不过,对于普通的理工科、社会科学工作来说,有时候我们并不需要把地图制作得非常精确。普通的分块填色数据地图就可以满足我们的要求。例如,在上一期中我们给出了姓氏、名字的全国分布地图姓氏分布-知乎@纯洁的夏老师optics.dicp.ac.cn下面介绍一种用P
严格绘制数据地图并不是一件简单的事情。专业的做法应当使用 GIS(地理信息系统)的专业软件。在这些软件中需要设置底图、投影方式、坐标、高程等等。不过,对于普通的理工科、社会科学工作来说,有时候我们并不需要把地图制作得非常精确。普通的分块填色数据地图就可以满足我们的要求。例如,在上一期中我们给出了姓氏、名字的全国分布地图
姓氏分布-知乎@纯洁的夏老师optics.dicp.ac.cn下面介绍一种用Phython绘制数据地图的方法,可以方便的从大量数据绘制出大量地图。
一、基本原理
首先我们需要一张底图。这张地图最好是PNG、BMP等无损格式的。如果是JPG等有损压缩格式,需要用Photoshop之类的图像处理软件进行预先二值化处理。下面是一张中国分省空白底图。
下面我们如何填充颜色呢?OpenCV 库有一个函数叫 floodFill 可以满足我们的要求。这个函数类似于 Windows 画图中的油漆桶工具,在某一点作用后会填充颜色直到形状的边缘。其调用格式为
floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]])
第一个参数 image 是图像矩阵,第二个参数 mask 在这里不需要设置为None即可。seedPoint就相当于使用油漆桶工具时用鼠标点击的位置坐标。newVal是新颜色的颜色值,可以用(r, g, b)元组来表示, r, g, b是0-255整数。后面的其他参数都是可选,不需要写。
二、获取所有分区坐标
现在我们首先需要知道所有省份的位置坐标。中国的省份不多,当然可以逐个在Photoshop里面查看记录坐标。但是如果是地级市地图呢?中国的地级市有1000多个,记录就会非常麻烦。在这里我们提供了一个小工具,可以方便实现坐标位置记录功能:
from chaco.api import ArrayPlotData, Plot
from enable.api import BaseTool
from enable.component_editor import ComponentEditor
from traits.api import HasTraits, Instance
from traitsui.api import Item, View
import cv2
class CustomTool(BaseTool):
def normal_left_down(self, event):
print self.component.map_data((event.x, event.y))
class ScatterPlot(HasTraits):
plot = Instance(Plot)
traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False),
width=800, height=600, resizable=True,
title="Custom Tool")
def _plot_default(self):
# Create the data and the PlotData object
z = cv2.imread('blank_map.png') #用你的图片替换这一行。
plotdata = ArrayPlotData(z=z)
# Create a Plot and associate it with the PlotData
plot = Plot(plotdata, default_origin="top left")
# Create a scatter plot in the Plot
plot.img_plot('z')
# Add our custom tool to the plot
plot.tools.append(CustomTool(plot))
return plot
test = ScatterPlot()
test.configure_traits()
这里利用了Chaco提供的交互式工具。运行后会显示一个包含有图片的窗口。只要单击图片,就自动在控制台打印单击位置的坐标。例如在这个截图中,我分别点击了江苏和浙江,这两个省份的坐标就记录在控制台。
我们拉一个表格,把所有省份名字都放进去,然后按表格顺序依次点击省份,再把控制台输出的坐标数据拷贝出来,得到一张表格:
11 北京市 (1331, 561)
12 天津市 (1365, 599)
13 河北省 (1305, 635)
14 山西省 (1208, 655)
15 内蒙古自治区 (1122, 549)
21 辽宁省 (1522, 525)
22 吉林省 (1585, 398)
23 黑龙江省 (1594, 256)
31 上海市 (1520, 924)
32 江苏省 (1465, 847)
33 浙江省 (1485,1001)
34 安徽省 (1376, 912)
35 福建省 (1437,1152)
36 江西省 (1342,1072)
37 山东省 (1385, 708)
41 河南省 (1271, 830)
42 湖北省 (1245, 977)
43 湖南省 (1176,1113)
44 广东省 (1291,1252)
45 广西壮族自治区 (1104,1225)
46 海南省 (1133,1432)
50 重庆市 (1056,1022)
51 四川省 (890, 968)
52 贵州省 (1039,1116)
53 云南省 ( 847,1249)
54 西藏自治区 (638, 986)
61 陕西省 (1082, 833)
62 甘肃省 (941, 800)
63 青海省 (698, 750)
64 宁夏回族自治区 (1010, 685)
65 新疆维吾尔自治区 (320, 505)
71 台湾省 (1542,1222)
三、利用ColorMap得到需要填充的颜色
Matplotlib给我们提供了多种多样的颜色-值映射关系。调用方法为
import matplotlib.cm as cm
cmap = cm.Blues #使用Blues作为映射函数
color = cmap(int(data[key] / max_ * 255))
color = [i * 255 for i in color]
其中 data[key] 是数据,max_ 是最大值。int(data[key]/ max_ *255) 可以把所有的数据转化为一个0-255的整数,这正是cmap函数对参数的要求。cmap函数的返回值是一个长度为 3 的元组,每一个值是 0-1 之间 的浮点数。[i *255for i in color] 可以把 color 转化为 0-255 的列表,这是 opencv 中 floodFill 函数对颜色的要求。
四、不同的映射函数填充效果
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)