0

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

I'm trying to do:

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

How can I fix that?

Mr. T
  • 11,960
  • 10
  • 32
  • 54
Flavio D
  • 1
  • 1
  • I suspect that you switched between latitude and longitude. Because the location is in remote South Atlantic. – swatchai May 27 '18 at 08:41

1 Answers1

0

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()

enter image description here

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

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

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

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

enter image description here

swatchai
  • 17,400
  • 3
  • 39
  • 58
  • I copy/paste your suggestion and I don't know why, but it keeps showing the same error msg: Traceback (most recent call last): File "", line 1, in 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 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 – Flavio D May 27 '18 at 13:39
  • I've tried with python2.7 and it works. There is something in the code to adapt to python 3.5? – Flavio D May 27 '18 at 13:40
  • @FlavioD Nothing at all. – swatchai May 29 '18 at 01:50
  • @FlavioD yes there is a big difference concerning integer division between Python 2 and 3 and it appears that this difference has not been properly accounted for in Basemap for Python 3. See [here](https://stackoverflow.com/a/48624707/2454357) for an example on how you can get around the problem. – Thomas Kühn May 30 '18 at 12:37