PythonGIS可视化—Matplot basemap工具箱

原文链接:http://www.douban.com/group/topic/32821988/

原文链接:http://www.cnblogs.com/vamei/archive/2012/09/16/2687954.html

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

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

数据如下(我从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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
主要是为了写个代码,以后用得着时可以直接调用,文件里的类直接继承QWidget,可以作为部件放入Layout中,省的以后还要麻烦重复的写代码。本人气象行业,会用到地图叠加风羽。 ---------- 主要实现了以下功能: 1. 绘制正常的折线或散点图(可以多条折线) 2. 绘制色斑图(等高线图) 3. 将数组显示为图片(主要是自己要用于卫星云图显示) 4. 利用basemap,在地图地图上添加风羽(风杆) ---------- 暂时先实现这些功能,方便再写界面的时候直接调用。basemap没有python3.6版本的,所以用的是非官方包。 文件说明: 一、总体说明 A、类 文件里分为两个类:PlotWidget和PlotGeoWidget文件里分为两个类:```PlotWidget```和```PlotGeoWidget``` B、用到的库 1、matplotlib(2.0.2) 2、PyQt5(5.6) 3、basement(第三方非官方包) 4、numpy(1.14.5) 5、math(python自带) 二、PlotWidget类 A、描述 该类作为一个独立的QWidget部件,可以直接放入Layout中作为一个普通部件 B、方法 1、plot_lines 功能:绘制线型图像(可多条曲线) ```def plot_lines(self, x_data, y_data, xlim=None, ylim=None, linestyle=['-'], linewidth=[2], linecolor=['black'], xticks=None, xlabels=None, x_labels_rotation=0, x_labels_fontsize=20, yticks=None, ylabels=None, y_labels_rotation=0, y_labels_fontsize=20, x_name=None, y_name=None, title=None, label=[None], label_loc='upper right')``` 参数解释: x_data、y_data: 要画的数据 必须在数据外面再套一个[],应为可能会容纳多组数据 例如只有一组数据[1,2,3,4,5],也需要在外面加上[]变成[[1,2,3,4,5]] xlim、ylim: 坐标轴范围,元组类型 例如:(0,100) linestyle、linewidth、linecolor: 线型线宽线色,列表 列表里每个元素都是按照matplotlib的线型线宽线色来表示 xticks、yticks: 坐标轴上要显示的刻度位置,列表类型 例如:[0,10,20,30] 代表在只显示10 20 30的刻度 xlabels、ylabels: 坐标轴上显示刻度位置要显示的文字,列表类型 前提是必须有xticks、yticks 例如:当xticks=[0,10,20,30]时,xlabels=['x', 'xx', 'xxx', 'xxxx']代表在0 10 20 30 刻度处显示'x', 'xx', 'xxx', 'xxxx'文字 x_labels_rotation、x_labels_fontsize、y_labels_rotation、y_labels_fontsize: 坐标轴上文字旋转角度和文字大小 x_name、y_name: 坐标轴标注 title: 图片题名 label: 图注,列表类型 label_loc: 图注位置,按照matplotlib图注规范 2、plot_contour 功能:画等值线图 ```def plot_contour(self, x_data, y_data, val, title=None, x_name=None, y_name=None, xticks=None, xlabels=None, x_labels_rotation=0, x_labels_fontsize=20, yticks=None, ylabels=None, y_labels_rotation=0, y_labels_fontsize=20)``` 参数解释: x_data、y_data、val: 要画的数据(x,y,z值) title: 图片题名 x_name、y_name: 坐标轴标注 xticks、yticks: 坐标轴上要显示的刻度位置,列表类型 xlabels、ylabels: 坐标轴上显示刻度位置要显示的文字,列表类型 x_labels_rotation、x_labels_fontsize、y_labels_rotation、y_labels_fontsize: 坐标轴上文字旋转角度和文字大小 3、plot_digital_image 功能:显示数字图像,如云图、照片等,但是需要先将图片转为数组 ```def plot_digital_image(self, img)``` 参数解释: img: 图片的数组 三、PlotGeoWidget A、描述 该类作为一个独立的QWidget部件,可以直接放入Layout中作为一个普通部件 B、方法 1、map_wind 功能:显示本场周边地区地图,在地图上画出风杆 ```def map_wind(self, lon, lat, spe, dir)``` 参数解释: lon、lat: 经纬度,以小数表示 spe、dir: 风速风向

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值