1

I'm plotting multiple points in Basemap and would like to have a legend to signify the category that each color represents. However, since I have multiple points in each category, the legend pulls each of those points, giving me multiple entries of the same category in the legend. Is there a way to just show one overall color-category listing?

m = Basemap(llcrnrlon=30.,llcrnrlat=20.,urcrnrlon=-160.,urcrnrlat=63.,projection='lcc',resolution='c',lat_1=20.,lat_2=40.,lon_0=90.,lat_0=50.)

X,Y = m(lon,lat)    
m.drawcountries()
m.drawmapboundary(fill_color='lightblue')
m.drawparallels(np.arange(0.,90.,5.),color='gray',dashes=[1,3],labels=[1,0,0,0])
m.drawmeridians(np.arange(0.,360.,15.),color='gray',dashes=[1,3],labels=[0,0,0,1])
m.fillcontinents(color='beige',lake_color='lightblue')
plt.title('MERRA-Observation Correlations')

for j in range(len(corr)):
    if j == 0 or j == 1 or j ==2:
        m.plot(X[j],Y[j],'o',color='orange',markersize=np.absolute(corr[j])*17.5,label='Prairie')
    if j == 3 or j ==4 or j == 5:
        m.plot(X[j],Y[j],'o',color='violet',markersize=np.absolute(corr[j])*17.5,label='Tundra')
    if j ==6 or j == 7 or j == 8:
        m.plot(X[j],Y[j],'o',color='purple',markersize=np.absolute(corr[j])*17.5,label='Taiga')
    plt.legend()

NOTE: I've placed plt.legend both inside and outside the loop with the same results.

enter image description here

DJV
  • 863
  • 3
  • 15
  • 30

3 Answers3

3

You seem to be plotting a whole new line for each data point. A scatter plot might be more appropriate: instead of your j loop, try:

scale = 17.5
m.scatter(X[:3], Y[:3], color='orange', s=abs(corr[:3])*scale, label='Prairie')
m.scatter(X[3:6], Y[3:6], color='violet', s=abs(corr[3:6])*scale, label='Tundra')
m.scatter(X[6:], Y[6:], color='purple', s=abs(corr[6:])*scale, label='Taiga')

(untested: I don't have your data).

xnx
  • 24,509
  • 11
  • 70
  • 109
1

Instead of passing the legend kwarg, you can retain a handle to the object returned by m.plot. You can then create the legend manually with only the plots you want to keep.

how to add legend for scatter()? has a good example.

Community
  • 1
  • 1
AMacK
  • 1,396
  • 9
  • 9
1

Another way: replace your call to plt.legend() with this and do it outside the for-loop:

ax = plt.gca()
handles, labels = ax.get_legend_handles_labels()
legend = plt.legend([handles[0],handles[3],handles[6]], labels[0],labels[3],labels[6]])

this pulls apart the stuff that's set up by plot (scatter, etc) calls to be sent to legend, so you can see how you might alter legends differently.

xnx's scatter solution also looks good.

p.s. -- this doesn't have anything to do with basemap, it's general to matplotlib plotting.

cphlewis
  • 15,759
  • 4
  • 46
  • 55