5

I have 79 lat and lons that I have data for to plot on a Basemap in Python. I have an array of 79 numbers to go along with it that I would like to plot instead of a normal dot (i.e. I would like a "1" or a "2" to show up instead of a usual dot). I tried the plt.annotate function, but that didn't work.

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

locs = np.genfromtxt('/Volumes/NO_NAME/Classwork/OK_vic_grid.txt')
lat = locs[:,1] # 79 values
lon = locs[:,2] # 79 values

m = Basemap(projection='stere',lon_0=-95,lat_0=35.,lat_ts=40,\
        llcrnrlat=33,urcrnrlat=38,\
        llcrnrlon=-103.8,urcrnrlon=-94) 

X,Y = m(lon,lat)    
m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.drawmapboundary(fill_color='lightblue')
m.drawparallels(np.arange(0.,40.,2.),color='gray',dashes=[1,3],labels=[1,0,0,0])
m.drawmeridians(np.arange(0.,360.,2.),color='gray',dashes=[1,3],labels=[0,0,0,1])

m.scatter(X,Y)
????? (Want to plot an array "maxpc" which has 79 numbers that I want to plot the string of)

OK_vic_grid.txt:

1   33.75   -97.75
2   33.75   -97.25
3   33.75   -96.75
4   33.75   -96.25
5   33.75   -95.75
6   33.75   -95.25
7   33.75   -94.75
8   34.25   -99.75
9   34.25   -99.25
10  34.25   -98.75
11  34.25   -98.25
12  34.25   -97.75
13  34.25   -97.25
14  34.25   -96.75
15  34.25   -96.25
16  34.25   -95.75
17  34.25   -95.25
18  34.25   -94.75
19  34.75   -99.75
20  34.75   -99.25
21  34.75   -98.75
22  34.75   -98.25
23  34.75   -97.75
24  34.75   -97.25
25  34.75   -96.75
26  34.75   -96.25
27  34.75   -95.75
28  34.75   -95.25
29  34.75   -94.75
30  35.25   -99.75
31  35.25   -99.25
32  35.25   -98.75
33  35.25   -98.25
34  35.25   -97.75
35  35.25   -97.25
36  35.25   -96.75
37  35.25   -96.25
38  35.25   -95.75
39  35.25   -95.25
40  35.25   -94.75
41  35.75   -99.75
42  35.75   -99.25
43  35.75   -98.75
44  35.75   -98.25
45  35.75   -97.75
46  35.75   -97.25
47  35.75   -96.75
48  35.75   -96.25
49  35.75   -95.75
50  35.75   -95.25
51  35.75   -94.75
52  36.25   -99.75
53  36.25   -99.25
54  36.25   -98.75
55  36.25   -98.25
56  36.25   -97.75
57  36.25   -97.25
58  36.25   -96.75
59  36.25   -96.25
60  36.25   -95.75
61  36.25   -95.25
62  36.25   -94.75
63  36.75   -102.75
64  36.75   -102.25
65  36.75   -101.75
66  36.75   -101.25
67  36.75   -100.75
68  36.75   -100.25
69  36.75   -99.75
70  36.75   -99.25
71  36.75   -98.75
72  36.75   -98.25
73  36.75   -97.75
74  36.75   -97.25
75  36.75   -96.75
76  36.75   -96.25
77  36.75   -95.75
78  36.75   -95.25
79  36.75   -94.75
7
  • What is your question exactly? A little more background might help get to an answer. Commented Sep 22, 2015 at 2:05
  • @skywalker I would like a scatter plot on my Basemap, but instead of dots at each lat-lon location, I want to have the numbers that I have contained in "maxpc" show up. Commented Sep 22, 2015 at 2:06
  • Could you gist OK_vic_grid.txt? Commented Sep 22, 2015 at 2:15
  • Why not a heat map? You literally want to see the numeric value at each longitude and latitude? Just curious. Commented Sep 22, 2015 at 2:20
  • @skywalker I'm not familiar with a heat map. But yeah, I just want numbers that I have in the maxpc array at each of those lat and lons instead of dots. Commented Sep 22, 2015 at 2:21

1 Answer 1

8

ax.scatter and ax.text both expect a single x, y point, rather than an array of locations.

Either will work perfectly fine, but you'll need to use a loop.

For example:

import numpy as np
import matplotlib.pyplot as plt

xy = np.random.random((5, 2))
text = ['A', 'B', 'C', 'D', 'E']

fig, ax = plt.subplots()
for (x,y), label in zip(xy, text):
    ax.text(x, y, label, ha='center', size=20)
plt.show()

enter image description here

With basemap, you'll need project your longitudes and latitudes into projected map coordinates (i.e. your X and Y arrays). For example (I'll also use annotate here to offset the label by a few points):

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

num = 79
lat = 5 * np.random.random(num) + 33
lon = 10 * np.random.random(num) - 104

fig, ax = plt.subplots()
m = Basemap(projection='stere',lon_0=-95,lat_0=35.,lat_ts=40,
            llcrnrlat=33,urcrnrlat=38,
            llcrnrlon=-103.8,urcrnrlon=-94,
            resolution='h', ax=ax)

X,Y = m(lon,lat)
m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.drawmapboundary(fill_color='lightblue')
m.drawparallels(np.arange(0.,40.,2.),color='gray',dashes=[1,3],labels=[1,0,0,0])
m.drawmeridians(np.arange(0.,360.,2.),color='gray',dashes=[1,3],labels=[0,0,0,1])

ax.scatter(X,Y)

for i, (x, y) in enumerate(zip(X, Y), start=1):
    ax.annotate(str(i), (x,y), xytext=(5, 5), textcoords='offset points')

plt.show()

enter image description here

On a side note, you might also consider using cartopy instead of basemap. basemap has been more or less completely superseded by cartopy. Both are matplotlib-based mapping toolkits, cartopy is just a lot nicer, i.m.o.. The map axes are true subclasses of Axes, so there's no separate Basemap object, it's a true Axes, instead. Furthermore, Cartopy has a few more features than basemap, and is typically faster, in my experience.

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

7 Comments

Thanks for the response, Joe. I get an error message that says Basemap doesn't have annotate as an attribute when I run this.
@DJV - You'll need to use ax.annotate, instead of m.annotate. (I had a typo in the initial version. Editing now.)
Ahh, perfect! Thank you.
Joe, cartopy looks great. I have a free student copy of Canopy and it seems like I have to pay for it, though.
You can install it separately, regardless. I don't know what versions of Canopy provide it by default, but none of them should prevent you from installing it. (Incidentally, while Canopy is quite nice, you might have a look at Anaconda, as well, for a similar distribution under a more permissive license.)
|

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.