How can I put latitudes and longitudes on the map I plotted?

3,982 views
Skip to first unread message

LeonH

unread,
Apr 3, 2014, 5:37:11 AM4/3/14
to scitoo...@googlegroups.com
I guess I could get the pyplot axis object and create labels and go through that rigamarole, but for such a common requirement there must be a function already? Does anyone an easy way to do it?

I notice in the iris gallery that not a single one of the latitude/longitude maps have tickmarks and tickmark labels on the axes. Whatever is the best solution to this task, it could usefully be put onto one of the existing plots in the gallery.

Andrew Dawson

unread,
Apr 3, 2014, 6:12:42 AM4/3/14
to scitoo...@googlegroups.com
This depends somewhat on what map projection you are using, and what labels you want to produce.
 
Cartopy has poor support for tick marks and labels generally, but you have a few options.
 
* You can supply the draw_labels argument to ax.gridlines(). Labels are only possible for a limited set of projections, and it will put labels on all sides of the plot. It is quite inflexible at the moment (needs dev attention) so if you don't like the result it is hard to change.
 
* You can use the set_xticks() and set_yticks() method of the axes. The cartopy versions of these accept a crs argument (see http://www.scitools.org.uk/cartopy/docs/latest/matplotlib/geoaxes.html#cartopy.mpl.geoaxes.GeoAxes.set_xticks) but again only support a limited number of projections. After you have located the ticks you will likely need to format them. The ticks are always drawn in projection coordinates, so if you want to label lat/lon on a projection that isn't just PlateCarree you will have some work to do. If you are using PlateCarre with a central longitude of 0 to plot then you can use the tick formatters defined in cartopy.mpl.gridliner (LATITUDE_FORMATTER and LONGITUDE_FORMATTER). If you have a different projection or even a different central longitude you will likely be out of luck and you'll have to set the labels manually.
 
A small bit of good news: there is an open PR to cartopy that provides projection aware tick formatters. These are limited to labelling lat/lon values but they will get the values right no matter what central longitude you have should work for all rectangular projections.
 
Labelling is an area where cartopy really falls down and something needs to be done about it before cartopy can really take off, so I'm glad you brought this up!

LeonH

unread,
Apr 3, 2014, 8:58:42 AM4/3/14
to scitoo...@googlegroups.com
I did say map, I can see why you thought I was messing with cartopy. My request is even simpler than that. I am using iris.plot.contourf() to plot a 2D cube (latitude and longitude) and I just want ticklabels and ticks on my axes! My problem is the same as if you changed this code so that the plot output has latitude and longitude ticklabels and ticks on it.
If you use
plt.contourf(cube.coord('longitude').points, cube.coord('latitude').points,  cube.data)

then the ticklabels and ticks are there, but they aren't with iris.plot.contourf(). I think the solution may be to give iris.plot.contourf() the axes as well, but I can't quite get it to work. This is the closest I get:
iplt.contourf(eddyVar, coords=['latitude', 'longitude'])

But unfortunately it swaps the axes so that longitude is the vertical axis and latitude is the horizontal axis. Switching the order of 'latitude' and 'longitude' doesn't work, the axis ticklabels and ticks magically disappear. Can anyone help?

Phil Elson

unread,
Apr 3, 2014, 9:16:26 AM4/3/14
to LeonH, scitoo...@googlegroups.com
When you produce a plot that is latitude vs longitude in Iris you are producing a cartopy map, so @ajdawson's comments are pertinent.

plt.gca().gridlines(draw_labels=True)

Might be just what you need. Further info can be found at http://scitools.org.uk/cartopy/docs/latest/matplotlib/gridliner.html.

HTH


--
You received this message because you are subscribed to the Google Groups "Iris" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scitools-iri...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Dawson

unread,
Apr 3, 2014, 9:18:12 AM4/3/14
to scitoo...@googlegroups.com
I think you are misunderstanding what I was trying to say.
 
I did say map, I can see why you thought I was messing with cartopy.
 
Iris uses cartopy to plots maps, iris.plot is a convenient wrapper around cartopy plotting functionality. If you are plotting maps in iris then you are using cartopy.
 
I am using iris.plot.contourf() to plot a 2D cube (latitude and longitude) and I just want ticklabels and ticks on my axes!
 
As I said before you can either choose to add tick labels or go with cartopy's gridline labelling:
 
iplt.contourf(mydata)
ax
= plt.gca()
ax
.gridlines(draw_labels=True)
# or..
ax
.set_xticks([-40, -20, 0, 20, 40], crs=ccrs.PlateCarree())
 
Again, as I said before, these options are both a bit limited, and your mileage may vary depending on what map projection you are plotting on (iris.plot will choose the map projection of the data if it is defined or PlateCarree otherwise). For PlateCarre projections everything goes quite smoothly, for others you will need to mess with the labels to get lat/lon values from the native projection tick locations. PR#401 on cartopy (https://github.com/SciTools/cartopy/pull/401) should make this much easier in future.
 
Switching the order of 'latitude' and 'longitude' doesn't work, the axis ticklabels and ticks magically disappear
 
Cartopy disables the tick marks by default (because they don't always make sense) and since iris is just using cartopy this is why you see this behaviour.
 
Also beware of that particular example, it is from Iris 0.9 when iris was using basemap internally for plotting! There should be an up-to-date version in the current online docs: http://www.scitools.org.uk/iris/docs/latest/examples/graphics/custom_file_loading.html#custom-file-loading

LeonH

unread,
Apr 3, 2014, 11:24:47 AM4/3/14
to scitoo...@googlegroups.com
Thanks Andrew and Phil, it is all a lot clearer now!
My final solution was a hybrid of the two methods. ax.gridlines(draw_labels=True) would have been fine, but it interferes with the title of the plot by writing labels on top of it. But this looks good:

        plt.gca().set_yticks([-60, -30, 0, 30, 60], crs=ccrs.PlateCarree())
        plt
.gca().set_xticks(np.arange(-180, 240, 60), crs=ccrs.PlateCarree())
        plt
.gca().gridlines()



Reply all
Reply to author
Forward
0 new messages