Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python. Draw rectangle in basemap

I need to add several rectangles in my basemap. I nee four rectangles with lat and log ranges as below.

1) llcrnrlon=-10, urcrnrlon=10, llcrnrlat=35,urcrnrlat=60

2) llcrnrlon=10.5, urcrnrlon=35, llcrnrlat=35,urcrnrlat=60

3) llcrnrlon=35.5, urcrnrlon=52, llcrnrlat=30,urcrnrlat=55

4) llcrnrlon=-20, urcrnrlon=35, llcrnrlat=20,urcrnrlat=34.5

My script is below. I found "polygon" packages to add lines but I do not exactly know how to do. Please help me!! Thanks a lot for your help in advance!

    from mpl_toolkits.basemap import Basemap

     m=basemaputpart.Basemap(llcrnrlon=-60, llcrnrlat=20, urcrnrlon=60, urcrnrlat=70, resolution='i', projection='cyl', lon_0=0, lat_0=45)

    lon1=np.array([[-180.+j*0.5 for j in range(721)]  for i in range(181)])
    lat1=np.array([[i*0.5 for j in range(721)]  for i in range(181)  ])
    Nx1,Ny1=m(lon1,lat1,inverse=False)

    toplot=data[:,:]
    toplot[data==0]=np.nan
    toplot=np.ma.masked_invalid(toplot)
    plt.pcolor(Nx1,Ny1,np.log(toplot),vmin=0, vmax=5)
    cbar=plt.colorbar()

    m.drawcoastlines(zorder=2)
    m.drawcountries(zorder=2)

    llcrnrlon = -10
    urcrnrlon =  10
    llcrnrlat =  35
    urcrnrlat =  60
    lower_left = (llcrnrlon, llcrnrlat)
    lower_right= (urcrnrlon, llcrnrlat)
    upper_left = (llcrnrlon, urcrnrlat)
    upper_right= (urcrnrlon, urcrnrlat)

    plot_rec(m, lower_left, upper_left, lower_right, upper_right)

Then I see "Type Error: 'tuple' object is not callable"

Instead of this part, I added one you suggested first.

    ..
    m.drawcoastlines(zorder=2)
    m.drawcountries(zorder=2)

    def plot_rec(m, lower_left, upper_left, lower_right, upper_right):
        xs = [lower_left[-10], upper_left[-10],
              lower_right[10], upper_right[10]]
        ys = [lower_left[35], upper_left[60],
              lower_right[35], upper_right[60]]
        m.plot(xs,ys,latlon=True)

    plt.show()

Then I do not see any box in my plot. I have to put another, not plt.show()??

Also, would you let me know how to put number in the box (e.g., 1 in the upper left conner of the box) ? How to get sum of values in all points of my data and get percentage of (sume of values in the box) over (sum of values in all points of my data)? I ask too much.. Just let me know what you can give me, it would be anyway great!!!

THanks a lot!!

like image 545
user2928318 Avatar asked Mar 20 '23 11:03

user2928318


1 Answers

The tricky thing about this is that a 'rectangle' isn't really a 'rectangle' on many, many projection types. So when you say 'rectangle', do you mean an actual rectangle in map-space, or simply a rectangle in pixel-space? The two require very different

But let's assume you want it in map-space. The quickest way is to just use Basemap's plot method, like so:

def plot_rec(bmap, lower_left, upper_left, lower_right, upper_right):
    xs = [lower_left[0], upper_left[0],
          lower_right[0], upper_right[0],
          lower_left[0], lower_right[0],
          upper_left[0], upper_right[0]]
    ys = [lower_left[1], upper_left[1],
          lower_right[1], upper_right[1],
          lower_left[1], lower_right[1],
          upper_left[1], upper_right[1]]
    bmap.plot(xs, ys, latlon = True)

where bmap is your map, and lower_left etc. are lon-lat tuples at those corners.

Update with use examples:

You asked for a usage example, so here you go:

m=basemaputpart.Basemap(llcrnrlon=-60, llcrnrlat=20, urcrnrlon=60, urcrnrlat=70, resolution='i', projection='cyl', lon_0=0, lat_0=45)

# your other setting up the map code here

# here I draw the first rectangle
llcrnrlon = -10
urcrnrlon =  10
llcrnrlat =  35
urcrnrlat =  60
lower_left = (llcrnrlon, llcrnrlat)
lower_right= (urcrnrlon, llcrnrlat)
upper_left = (llcrnrlon, urcrnrlat)
upper_right= (urcrnrlon, urcrnrlat)

plot_rec(m, lower_left, upper_left, lower_right, upper_right) # This calls the function I defined before

# Rinse and repeat for the other lat/lon combos

plt.show()

You can definitely do this more elegantly using list comprehensions to generate the correct corner-point sets, but this should get you started.

Update 2

So it appears there is some confusion here. plot_rec is a function. It should be placed somewhere not inline with the rest of your script. By itself, it doesn't do anything. It does when you call it here:

...
upper_left = (llcrnrlon, urcrnrlat)
upper_right= (urcrnrlon, urcrnrlat)
# This next line is where we call the function
plot_rec(m, lower_left, upper_left, lower_right, upper_right)
like image 169
aruisdante Avatar answered Mar 23 '23 11:03

aruisdante