0
votes

I've started working with Basemap, which seems potentially very useful.

If I plot some global data on a latitude/longitude grid as filled contours, it works great: Iff I leave the lat_0 and lon_0 as zero. Once I change the center location, the map moves but the data doesn't. I would be grateful for advice.

I've created a simple version of the code I'm using, with some simple sample data that illustrates the problem. The values should be (are) large at the equator but small at the poles. If you run the code with lat_0 and lon_0 = 0, it works fine. But if you change the center location to a different coordinate, the same pattern/data is presented even though the map has moved.

from mpl_toolkits.basemap import Basemap, cm
import matplotlib.pyplot as plt
import numpy as np

# create data 

lat = np.linspace(-90,90,num=180)
lon = np.linspace(-180,180,num=361)

h2o_north = np.linspace(1,65,num=90)
h2o_south = np.flipud(h2o_north)
h2o = np.append(h2o_north,h2o_south)

data = np.transpose(np.tile(h2o,(len(lon),1)))

# create figure and axes instances
fig = plt.figure(figsize=(10,10))
ax = fig.add_axes([0.1,0.1,0.8,0.8])

# create map
m = Basemap(projection='ortho',lon_0=-50,lat_0=50,resolution='l')

# draw coastlines and country boundaries
m.drawcoastlines()
m.drawcountries()
# draw parallels
parallels = np.arange(-90.,90,10.)
m.drawparallels(parallels)

# draw meridians
meridians = np.arange(180.,360.,10.)
m.drawmeridians(meridians)

ny = data.shape[0]
nx = data.shape[1]
lons, lats = m.makegrid(nx, ny) # get lat/lons of ny by nx evenly space grid
x, y = m(lons, lats)            # compute map projection coordinates

# draw filled contours.
clevs = np.linspace(0,70,num=281)
cs = m.contourf(x,y,data,clevs,cmap=plt.cm.jet)

# colorbar
cbar = m.colorbar(cs,location='bottom',pad="5%",ticks=np.linspace(0,70,15))
cbar.set_label('Scale of the data')

plt.title('Some global data', fontsize=14)
1

1 Answers

0
votes

Use np.meshgrid() to create the meshgrid of lon-lat, then, convert it to projection coordinates, and the data are ready to generate contours and plot.

Here is the working code:

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np

# data for z (2D array)
h2o_north = np.linspace(1, 65, num=90)
h2o_south = np.flipud(h2o_north)
h2o = np.append(h2o_north, h2o_south)
data = np.transpose(np.tile(h2o, (len(h2o_north), 1)))

# create figure and axes instances
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot()

# create basemap instance
m = Basemap(projection='ortho', lon_0=-50, lat_0=50, resolution='c', ax=ax)

# create meshgrid covering the whole globe with ...
# conforming dimensions of the `data`
lat = np.linspace(-90, 90, data.shape[0])
lon = np.linspace(-180, 180, data.shape[1])
xs, ys = np.meshgrid(lon, lat)   # basic mesh in lon, lat (degrees)
x, y = m(xs, ys)                 # convert (lon,lat) to map (x,y)

# draw filled contours
clevs = np.linspace(0, np.max(data), 60)
cs = m.contourf(x, y, data, clevs, cmap=plt.cm.jet)
m.drawcoastlines()
m.drawcountries()

m.drawmeridians(range(-180, 180, 30))
m.drawparallels(range(-90, 90, 30))

# draw colorbar
cbar = m.colorbar(cs, location='bottom', pad="5%", ticks=np.linspace(0, np.max(data), 5))
cbar.set_label('Scale of the data')

plt.show()

The resulting plot:

enter image description here