如何在地图(底图)上绘制插值站数据? [英] How to plot interpolate station data over a map (basemap)?

查看:330
本文介绍了如何在地图(底图)上绘制插值站数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文件,该文件在5个站点中累积了一个月的降雨量. csv文件中有纬度,经度和降雨数据.我的文件就是这样:

I've got a file with accumulated rainfall over a month in 5 stations. There are lat, lon and rain data in csv file. My file is just like that:

Out[18]: 
         lat       lon  rain
0 -48.379000 -1.067000  213.0
1 -48.435548 -1.401513  157.2
2 -48.482217 -1.449707  147.0
3 -48.457779 -1.249272  182.6
4 -48.479847 -1.308735   49.4

我正在尝试:

import numpy as np
import pandas as pd
from matplotlib.mlab import griddata
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)

 data = pd.read_csv('.../rainfall-2010-12.txt',na_values=['NaN'], sep=',')
norm = Normalize()

#mapextent
lllon = data['lon'].min()
lllat = data['lat'].min()
urlon = data['lon'].max()
urlat = data['lat'].max()

#Basemap
m = Basemap(
    projection = 'merc',
    llcrnrlon = lllon, llcrnrlat = lllat, urcrnrlon = urlon, urcrnrlat = urlat,
    resolution='h')

# transform lon / lat coordinates to map projection
data['projected_lon'], data['projected_lat'] = m(*(data.lon.values, data.lat.values))

#griddata
numcols, numrows = 300, 300
xi = np.linspace(data['projected_lon'].min(), data['projected_lon'].max(), numcols)
yi = np.linspace(data['projected_lat'].min(), data['projected_lat'].max(), numrows)
xi, yi = np.meshgrid(xi, yi)

#interpolate
x, y, z = data['projected_lon'].values, data['projected_lat'].values, data.rain.values
zi = griddata(x, y, z, xi, yi, interp='linear')

m.drawcoastlines()

# contour plot
conf = m.contourf(xi, yi, zi, zorder=4, alpha=0.6, cmap='RdPu')

cbar = plt.colorbar(conf, orientation='horizontal', fraction=.057, pad=0.05)
cbar.set_label("Rainfall - mm")

plt.title("Rainfall")
plt.show()

但是当我尝试运行时,出现了此错误消息:

But when I'm trying to run, I got this error msg:

/usr/local/lib/python3.5/dist-packages/mpl_toolkits/basemap/__init__.py:3608: MatplotlibDeprecationWarning: The ishold function was deprecated in version 2.0.   b = ax.ishold() /usr/local/lib/python3.5/dist-packages/mpl_toolkits/basemap/__init__.py:3675: MatplotlibDeprecationWarning: axes.hold is deprecated.
    See the API Changes document (http://matplotlib.org/api/api_changes.html)
    for more details.   ax.hold(b) Traceback (most recent call last):

  File "<ipython-input-17-cb8133160e02>", line 4, in <module>
    conf = m.contourf(xi, yi, zi, zorder=4, alpha=0.6, cmap='RdPu')

  File "/usr/local/lib/python3.5/dist-packages/mpl_toolkits/basemap/__init__.py", line 521, in with_transform
    return plotfunc(self,x,y,data,*args,**kwargs)

  File "/usr/local/lib/python3.5/dist-packages/mpl_toolkits/basemap/__init__.py", line 3644, in contourf
    xx = x[x.shape[0]/2,:]

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

我该如何解决?

推荐答案

您的代码中没有严重错误. (1)由于所有点都位于南大西洋,我怀疑(纬长)是相反的. (2)数据文件中的内容第一行不应有多余的空格.

There is no serious error in your code. (1) I suspect that (Lat, long) is reversed because all points are located in South Atlantic. (2) Content in data file should not have extra spaces on the first line.

这是数据.第一行没有多余的空格.

This is the data. No extra spaces on the first line.

lat,lon,rain
0, -48.379000, -1.067000,  213.0
1, -48.435548, -1.401513,  157.2
2, -48.482217, -1.449707,  147.0
3, -48.457779, -1.249272,  182.6
4, -48.479847, -1.308735,   49.4

这是基于您的工作代码以及生成的地图. 请注意,我注释掉了绘制地形特征的部分.它们对当前数据毫无用处.

Here is the working code based on yours, and the resulting map. Note that I commented out the parts that plot land features. They are useless with the current data.

import numpy as np
import pandas as pd
from matplotlib.mlab import griddata
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
from math import ceil

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)

data = pd.read_csv('rainfall-2010-12.txt', na_values=['NaN'], sep=',')
norm = Normalize()

#mapextent
lllon = data['lon'].min()
lllat = data['lat'].min()
urlon = data['lon'].max()
urlat = data['lat'].max()

#Basemap
pad = 0.01  # padding around map extents
m = Basemap(
    projection = 'merc', \
    llcrnrlon = lllon - pad, \
    llcrnrlat = lllat - pad, \
    urcrnrlon = urlon + pad, \
    urcrnrlat = urlat + pad, \
    resolution='h', \
    ax=ax)

# transform lon / lat coordinates to map projection
data['projected_lon'], data['projected_lat'] = m(*(data.lon.values, data.lat.values))

#griddata
numcols, numrows = 100, 100
xi = np.linspace(data['projected_lon'].min(), data['projected_lon'].max(), numcols)
yi = np.linspace(data['projected_lat'].min(), data['projected_lat'].max(), numrows)
xi, yi = np.meshgrid(xi, yi)

#interpolate
x, y, z = data['projected_lon'].values, data['projected_lat'].values, data.rain.values
zi = griddata(x, y, z, xi, yi, interp='linear')

# contours plot
conf = m.contourf(xi, yi, zi, zorder=4, alpha=0.6, cmap='RdPu')  # filled contour
cont = m.contour(xi, yi, zi, zorder=5)                           # line contour

# *** If the location is on land, uncomment this block of code ***
# draw some map features
#m.drawcoastlines()
#m.drawrivers(color='b')
#m.fillcontinents(color='lightyellow')

# paint the ocean
watercolor=np.array([0.6, 0.8, 0.9])
m.drawlsmask(land_color=watercolor, ocean_color=watercolor, lakes=False, resolution='i')

# draw parallels and meridians; also accompanying labels
m.drawparallels(np.arange(ceil(lllat*100)/100, ceil(urlat*100)/100, 0.05), \
                labels=[1,0,0,0], linewidth=0.2, dashes=[5, 3])   # draw parallels
m.drawmeridians(np.arange(ceil(lllon*100)/100, ceil(urlon*100)/100, 0.05), \
                labels=[0,0,0,1], linewidth=0.2, dashes=[5, 3])   # draw meridians

cbar = plt.colorbar(conf, orientation='horizontal', fraction=.057, pad=0.075)
cbar.set_label("Rainfall - mm")

plt.title("Rainfall")
plt.show()

(编辑1) 上面的代码相同,但是有2种不同的设置:

(Edit 1) With the same code above, but 2 different setups:

(1)Python 2.7.14/Basemap 1.1.0(conda-forge)

(1) Python 2.7.14 / Basemap 1.1.0 (conda-forge)

(2)Python 3.5.4/Basemap 1.1.0(conda-forge)

(2) Python 3.5.4 / Basemap 1.1.0 (conda-forge)

结果图在视觉上与以下所示相同, 左图:设置1,右图:设置2.

The resulting plots are visually the same as shown below, Left image: setup 1, right image: setup 2.

这篇关于如何在地图(底图)上绘制插值站数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆