SciTools / cartopy

Cartopy - a cartographic python library with matplotlib support
https://scitools.org.uk/cartopy/docs/latest
BSD 3-Clause "New" or "Revised" License
1.44k stars 369 forks source link

lack of gridlines control, bugs and undocumented behaviour #2005

Open snowzky opened 2 years ago

snowzky commented 2 years ago

Description

Gridlines now work for other than PlateCaree projections, great. Except the handling leaves much to desire. I am using a somewhat zoomed-in view of a specific region of the globe because that is where my data is, and I expect cartopy to also be able handle this kind of cases.

I propose adding the functionality and control to draw_labels - and importantly, to separate gridlines and labels thereof - just like it is in regular matplotlib plotting.

List of improvements

0) Add option for ticks to the axis, either inside or outside, just like for regular plots. Inside mean drawing the gridline slightly bigger for a few points.

1) No documentation of what keyword "geo" means in draw_labels, "For all labels one would use ["x", "y", "top", "bottom", "left", "right", "geo"]."

2) Bug? Setting x or y_inline to true while also using {"bottom": "x", "left": "y"} produces two instances of x or y labels respectively. What is the expected behavior? How can we get one instance of either x or y while also inline labeling?

image

3) No fine control of the inline placement: why can the user not specify the latitude placement for a longitude label and vice versa? The automatic inline is not always good. (see examples in this post).

4) xlocs and ylocs controls where to draw gridlines. But what if I want more gridlines than I want labels? This is a completely normal case, you might want to show latitude with lines every 3 degree spacing but you don't need to label intermediate lines. Just like for matplotlib, I wish to set xticks and xticklabels (and for y of course) separately.

5) Bugs or wrong behavior with LambertConformal ...? Could be related to issue 1943.

image

Code to reproduce

Example 2:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

dataproj=ccrs.PlateCarree()
mapproj=ccrs.PlateCarree()

fig,axs=plt.subplots(1,3, figsize=(30,10),subplot_kw={'projection':mapproj})

for ax in axs:
    ax.set_extent((3,27,53,73),crs=dataproj)
    ax.coastlines('10m') 
    ax.add_feature(cfeature.BORDERS, linestyle=':')

axs[0].gridlines(draw_labels=True)
axs[0].set_title('draw_labels=\nTrue')

axs[1].gridlines(draw_labels={"bottom": "x", "left": "y"})
axs[1].set_title('draw_labels=\n{"bottom": "x", "left": "y"}')

axs[2].gridlines(draw_labels={"bottom": "x", "left": "y"},y_inline=True)
axs[2].set_title('draw_labels=\n{"bottom": "x", "left": "y"},y_inline=True')

Example 5:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

dataproj=ccrs.PlateCarree()
mapproj=ccrs.LambertConformal(central_longitude=8, central_latitude=60, 
    false_easting=0.0, false_northing=0.0, secant_latitudes=None,
    standard_parallels=None, globe=None, cutoff=-30)

fig,axs=plt.subplots(2,2, figsize=(15,23),subplot_kw={'projection':mapproj})

for ax in axs.ravel():
    ax.set_extent((3,27,53,73),crs=dataproj)
    ax.coastlines('10m') 
    ax.add_feature(cfeature.BORDERS, linestyle=':')

axs[0][0].gridlines(draw_labels=True)
axs[0][0].set_title('draw_labels=\nTrue')

axs[0][1].gridlines(draw_labels={"bottom": "x", "left": "y"})
axs[0][1].set_title('draw_labels=\n{"bottom": "x", "left": "y"}')

axs[1][0].gridlines(draw_labels={"bottom": "x", "left": "y"},x_inline=False)
axs[1][0].set_title('draw_labels=\n{"bottom": "x", "left": "y"},x_inline=False')

axs[1][1].gridlines(draw_labels={"bottom": "x", "left": "y"},y_inline=True)
axs[1][1].set_title('draw_labels=\n{"bottom": "x", "left": "y"},y_inline=True')

My specific customization case

If anyone has tips or tricks to how I can get latitude y outside, longitude x inside, control placement of inline x label, correct rotation of potential outside x label, and more gridlines than labels - it would be much appreciated. I obviously came across these bugs/lack of control when trying to plot my specific cases. I maintain though that a level of control alike to matplotlib's xticks and xticklabels would be very useful for cartopy. If it can be obtained by switching to matplotlib, that would be okay too, but unfortunately there is not enough examples and documentation for that.

Full environment definition ### Operating system Linux Mint 19.1 ### Cartopy version 20.2
stefraynaud commented 2 years ago

Yes, there are many things to improve or clarify. Most of the complexity and limitations are due to the fact that we work in projected coordinate and that the map boundary is not always rectangular or circular. Have tried to set en negative padding?

I think, these points should be addressed one by one when relevant. Do you have a some time to spend on it? Pull requests+feedbacks should help.