Reputation: 535
I'm having a hard time with plotting a basemap with Matplotlib and I'm fairly new to it so I was hoping for some help.
I have data of the format:
[ (lat1, lon1, data1),
(lat2, lon2, data2),
(lat3, lon3, data3),
...
(latN, lonN, dataN) ]
And here is some sample data:
(32.0, -128.5, 3.99)
(31.0, -128.0, 3.5027272727272734)
(31.5, -128.0, 3.7383333333333333)
(32.0, -128.0, 3.624)
(32.5, -128.0, 3.913157894736842)
(33.0, -128.0, 4.443333333333334)
Finally, here are some basic statistics about my data that I'm planning to plot:
LAT MIN: 22
LAT MAX: 50
LAT LEN: 1919
LON MIN: -128
LON MAX: -97
LON LEN: 1919
DATA MIN: 0
DATA MAX: 12
DATA LEN: 1919
I need to contour plot on a basemap of the continental United States. I can't, for the life of me, seem to figure out how to setup the data for plotting.
I read that the X-Axis (LATS) needs to be a np.array, and Y-Axis (LONS) needs to be an np.array and that Z (DATA) needs to be a MxN matrix where M = len(LATS) and N = len(LONS). So to me, I see Z as a diagonal matrix where the diagonal contains the data on the diagonal is the values found in DATA corresponding to the index of LATS and LONS.
Here is my code:
def show_map(self, a):
a = sorted(a, key = lambda entry: entry[0]) # sort by latitude
a = sorted(a, key = lambda entry: entry[1]) # then sort by longitude
lats = [ x[0] for x in a ]
lons = [ x[1] for x in a ]
data = [ x[2] for x in a ]
lat_min = min(lats)
lat_max = max(lats)
lon_min = min(lons)
lon_max = max(lons)
data_min = min(data)
data_max = max(data)
x = np.array(lats)
y = np.array(lons)
z = np.diag(data)
m = Basemap(
projection = 'merc',
llcrnrlat=lat_min, urcrnrlat=lat_max,
llcrnrlon=lon_min, urcrnrlon=lon_max,
rsphere=6371200., resolution='l', area_thresh=10000
lat_ts = 20, resolution = 'c'
)
fig = plt.figure()
plt.subplot(211)
ax = plt.gca()
# draw parallels
delat = 10.0
parallels = np.arange(0., 90, delat)
m.drawparallels(parallels, labels=[1,0,0,0], fontsize=10)
# draw meridians
delon = 10.
meridians = np.arange(180.,360.,delon)
m.drawmeridians(meridians,labels=[0,0,0,1],fontsize=10)
# draw map features
m.drawcoastlines(linewidth = 0.50)
m.drawcountries(linewidth = 0.50)
m.drawstates(linewidth = 0.25)
ny = z.shape[0]; nx = z.shape[1] # make grid
lo, la = m.makegrid(nx, ny)
X, Y = m(lo, la)
clevs = [0,1,2.5,5,7.5,10,15,20,30,40,50,70,100,150,200,250,300,400,500,600,750]
cs = m.contour(X, Y, z, clevs)
plt.show()
The plot I get, however, is this: https://i.sstatic.net/ZigKh.jpg. I need something to this effect: http://matplotlib.org/basemap/_images/plotprecip.png
Can someone point out what I'm doing wrong and help me plot this? Thank You.
Thanks
Upvotes: 3
Views: 4507
Reputation: 21
Your linked gist is a solution but still wrong in another place.
In your question and in your linked gist you switched x and y coordinates with lon and lat.
x represents lon
y represents lat
Therefore you still get wrong results with your linked gist.
Upvotes: 1
Reputation: 535
I figured out how to do it. This is the code that I finally wrote, and I think this can help other users. If there is a better way of doing this, please state it, since I'm new to Matplotlib.
https://gist.github.com/3789221
Upvotes: 2
Reputation: 2251
why are you writing:
z = np.diag(data)
From the documentation, numpy.diag(v, k=0)
extracts a diagonal or construct a diagonal array.
That should be why you only get a "diagonal area" of values...
Upvotes: 0