3

I'm trying to wrap my head around matplotlib's basemap API. What I'd like to do is plot latitude and longitude data of a very small area (couple of km in either direction) on a cylindrical projection.

The problem is, I'm unable to understand how llcrnrlon, llcrnrlat, urcrnrlon and urcrnrlat parameters to the Basemap constructor work.

As far as I understand it, the llcrnrlon is the west-most longitude and llcrnrlat is the south-most latitude and urcrnrlon and urcrnrlat are the east-most and north-most longitude and latitude respectively.

In all these cases, given a set of coordinates, the (numerically) smallest longitudes are the west-most and the smallest latitudes are the south-most and vice-versa. Is this understanding correct?

I'm able to get the plot working by setting xlim and ylim on the underlying Axes object, but using the same values in the basemap constructor seem to push my data off the plot.

EDIT: See code below for a reproduction of the problem:

from matplotlib import pyplot
from mpl_toolkits import basemap
import random

lat_bounds = 52.063443, 52.072587 
long_bounds = 1.010408, 1.024502

ax1 = pyplot.subplot(121)
ax2 = pyplot.subplot(122)
ax1.set_title('With ll* rr*')
ax2.set_title('With default values')

my_map1 = basemap.Basemap(projection='cyl', llcrnrlat=lat_bounds[0], llcrnrlon=long_bounds[0], 
            urcrnrlat=lat_bounds[1], urcrnrlon=long_bounds[1], ax=ax1)

my_map2 = basemap.Basemap(projection='cyl', ax=ax2)

data_lats = [random.uniform(*lat_bounds) for i in xrange(50)]
data_lons = [random.uniform(*long_bounds) for i in xrange(50)]

my_map1.plot(data_lats, data_lons)
my_map2.plot(data_lats, data_lons)

pyplot.show()

In the figures below, the right hand side image is made by using Basemap(projection='cyl') and the left hand side image is made by using Basemap(projection='cyl', llcrnrlat=lat_bounds[0], llcrnrlon=long_bounds[0], urcrnrlat=lat_bounds[1], urcrnrlon=long_bounds[1], ax=ax1)

Notice the dot in the right hand side image, which when zoomed using the matplotlib toolbar becomes the second image.

Notice the dot in the right hand side image Right hand side image zoomed

2
  • You are right about the parameters. llcrnrlon stands for "lower left corner longitude" and so on. Also, "cyl" (cylindrical) is the default value for the projection keyword, so you are on the right track. You do need to watch for things like plotting over the antimeridian (180 E). Can you post the values you are trying to plot? Commented May 13, 2014 at 0:43
  • Also, manually setting ax1.set_xlim(*lat_bounds) and ax1.ylim(*long_bounds) does the trick. Commented May 13, 2014 at 14:23

1 Answer 1

4
+50

The problem in your example code is that you are passing the arguments to Basemap.plot() the wrong way around. The arguments to Basemap.plot are exactly the same as those to matplotlib.pyplot.plot, i.e.:

plot(x,y,*args,**kwargs)

In cylindrical coordinates, longitude is the x-coordinate and latitude is the y-coordinate, so you should do mymap1.plot(data_lons, data_lats). The reason it seemed to work in your second example is that longitudes of ~52 and latitudes of ~1 make sense. The points were plotted, but somewhere far away from your domain. If you panned the window of ax1 far enough, you would have seen them (which is the same as doing ax.set_xlim(lat_bounds) and ax.set_ylim(lon_bounds)).

Sign up to request clarification or add additional context in comments.

2 Comments

That was a great spot! I never would have found it!
Yeah by convention in GIS and cartography the order is (lat,lon)... this has caused me headaches before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.