Search code examples
pythonmatplotlibcartopy

How can I create a legend for a cartopy and Matplotlib plot in python?


I am classifying points of the earth (lon and lat coordinates) into categories based on variables for that point. I have an array (360 x 720) (the resolution of my lat, lon grid for earth) that contains the appropriate classification for each point as a number, there are 13 categories; a, b, c,... and in my 360x 720 array these categories are represented as 1, 2, 3,..., 13.

I can map this via cartopy and matplotlib, but i am stuck trying to make a legend/ key that shows what category each color mapped represents, the best i can get is an unhelpful colorbar.

 ax = plt.axes(projection=ccrs.PlateCarree()) #cartopy

preplot = plt.contourf(lons, lats, Map, 17,
             transform=ccrs.PlateCarree(), cmap = "tab20")
ax.coastlines() # cartopy
cb = plt.colorbar(preplot, orientation="horizontal")

plt.title("1901")

plt.show()

which gives: enter image description here A map and colorbar

Sorry if this is not all the needed info


Solution

  • If I understand your question correctly, you want to add labels for all 13 categories to your colorbar? In that case, you should set a total of 13 ticks on your colorbar (as you have 13 categories) using:

    cb.set_ticks([i for i in range(1, 14, 1)])
    

    Now, you should see a total of 13 ticks on your colorbar. However, currently the ticklabels are the numbers 1-13. To change this, you can use cb.set_ticklabels(<list_of_strings>). So, for example:

    cb.set_ticklabels(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'])
    

    In this case, your complete code would be:

    ax = plt.axes(projection=ccrs.PlateCarree()) #cartopy
    
    preplot = plt.contourf(lons, lats, Map, 17,
                 transform=ccrs.PlateCarree(), cmap = "tab20")
    ax.coastlines() # cartopy
    cb = plt.colorbar(preplot, orientation="horizontal")
    
    # Update the colorbar ticks + labels
    cb.set_ticks([i for i in range(1, 14, 1)])
    cb.set_ticklabels(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'])
    
    plt.title("1901")
    
    plt.show()