爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 47949|回复: 30

[经验总结] Python之地理信息可视化——matplot basemap工具箱

[复制链接]

新浪微博达人勋

发表于 2012-9-16 22:39:29 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 ztftom 于 2012-9-16 22:45 编辑

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

在数据可视化过程中,我们常常需要将数据根据其采集的地理位置在地图上显示出来。比如说我们会想要在地图上画出城市,飞机的航线,乃至于军事基地等等。通常来说,一个地理信息系统都会带有这样的功能。今天我们讨论如何在Python上实现,并且使用免费的工具包。

Matplot是python上常用的一个数据绘制包。它基于numpy(numpy是python用于数组运算的一个包)。Matplot具有强大的数据绘制功能,可以轻易地画出各种统计图形,比如散点图,条行图,饼图等等。而Matplot中的basemap则允许我们绘制出地图,并在地图上继续画出数据。
( Matplot经常与numpy和scipy相配合,用于科学研究。他们是Matlab的强劲对手,这相当可以理解,因为Matlab一套需要好几千块,而python工具则是免费的。)
我们今天的目标是用上述工具画出亚洲主要城市的人口。如下图所示,人口的多少以橙色小圆圈的大小表示:
image.png
数据如下(我从wikipedia上整理的,你可以随意使用),我将数据保存在文件major_city:


Shanghai 23019148  31.23N  121.47E  China
Mumbai   12478447  18.96N  72.82E   India
Karachi  13050000  24.86N  67.01E   Pakistan
Delhi    16314838  28.67N  77.21E   India
Manila   11855975  14.62N  120.97E  Philippines
Seoul    23616000  37.56N  126.99E  Korea(South)
Jakarta  28019545   6.18S  106.83E  Indonesia
Tokyo    35682460  35.67N  139.77E  Japan
Peking   19612368  39.91N  116.39E  China



第一列是城市名,第二列是人口,第三第四列为纬度和经度,最后一列为所在国家。

下面是我的Python代码:

# Written by Vamei, http://www.cnblogs.com/vamei/
#
Feel free to use or modify this script.
from
mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import
numpy as np
#============================================
#
read data
names = []
pops  
= []
lats  
= []
lons  
= []
countries
= []
for line in file("../data/major_city"):
    info
= line.split()
    names.append(info[0])
    pops.append(float(info[
1]))
    lat  
= float(info[2][:-1])
   
if info[2][-1] == 'S': lat = -lat
    lats.append(lat)
    lon  
= float(info[3][:-1])
   
if info[3][-1] == 'W': lon = -lon + 360.0
    lons.append(lon)
    country
= info[4]
    countries.append(country)
#============================================
#
set up map projection with
# use low resolution coastlines.
map = Basemap(projection='ortho',lat_0=35,lon_0=120,resolution='l')
# draw coastlines, country boundaries, fill continents.map.drawcoastlines(linewidth=0.25)map.drawcountries(linewidth=0.25)
# draw the edge of the map projection region (the projection limb)map.drawmapboundary(fill_color='#689CD2')
#
draw lat/lon grid lines every 30 degrees.
map.drawmeridians(np.arange(0,360,30))
map.drawparallels(np.arange(
-90,90,30))
#
Fill continent wit a different color
map.fillcontinents(color='#BF9E30',lake_color='#689CD2',zorder=0
)
# compute native map projection coordinates of lat/lon grid.
x, y = map(lons, lats)max_pop = max(pops)
#
Plot each city in a loop.# Set some parameters
size_factor = 80.0
y_offset    = 15.0
rotation    = 30
for i,j,k,name in zip(x,y,pops,names):
    size
= size_factor*k/max_pop
    cs
= map.scatter(i,j,s=size,marker='o',color='#FF5600')
    plt.text(i,j
+y_offset,name,rotation=rotation,fontsize=10)

plt.title(
'Major Cities in Asia & Population')
plt.show()




程序分为两个部分,第一部分为从文件读取数据并处理,第二部分是用basemap绘图。
map = Basemap(projection='ortho',lat_0=35,lon_0=120,resolution='l')
设置了地图投影的方法。从球形的地球表面投影到平面地图有许多方法可以选择,得到的结果也非常不同。

我们的经纬度通过
x, y = map(lons, lats)
语句转换为图像上的位置,并通过
cs = map.scatter(i,j,s=size,marker='o',color='#FF5600')
画散点图的方法在地图上画出来。

文中的需要的软件包包括:

numpy, matplot, mpl_toolkits

你可以google并找到它们。

另外,如果是也可以下载epd python。它整合了python以及所有的软件包。(epd python是商业版,但对于学术用户免费。)

评分

参与人数 1金钱 +22 贡献 +4 体力 +80 收起 理由
言深深 + 22 + 4 + 80 很给力!

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

0
早起挑战累计收入
发表于 2012-9-17 09:40:05 | 显示全部楼层
楼主的教程都不错,我也得学学python,看来画这种图用py挺容易的
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 成长值: 0
发表于 2012-9-17 10:56:55 | 显示全部楼层
尽管是转载的,也是好东西啊!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2012-9-17 13:42:01 | 显示全部楼层
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2012-9-17 13:43:19 | 显示全部楼层
mofangbao 发表于 2012-9-17 09:40
楼主的教程都不错,我也得学学python,看来画这种图用py挺容易的

我也还在摸索,但画图用起来感觉是不错。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 成长值: 0
发表于 2012-9-17 14:16:41 | 显示全部楼层
ztftom 发表于 2012-9-17 13:42
:-),其实是从我自己的博客转载的。

哈哈,看来加分没加错
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-5-4 22:33:47 | 显示全部楼层
这个很不错啊
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-5-4 22:34:03 | 显示全部楼层
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-1-21 08:59:17 | 显示全部楼层
很好,谢谢!!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2014-2-19 11:24:57 | 显示全部楼层
很好很好很好很好很好很好很好
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表