Skip to content

Missing region border when specifying a projection; In addition: a (faster) alternative to using projections #109

Closed
@mherrmann3

Description

@mherrmann3

1. A bug: the region border is not projected

When using 'projection': cartopy.crs.Mercator() in plot_args to csep.utils.plots.plot_spatial_dataset (i.e., via csep.core.forecasts.GriddedForecast.plot, the region boundary disappears. This doesn't happen if not specifying this argument (i.e., when PlateCaree is used).

Suggested fix: add transform=cartopy.crs.PlateCarree() to the .plot() command here.

2. A (faster) alternative to using projections

Instead of using a fancy projections (i.e. everything else than PlateCaree), you may consider to simply scale the axes according to the currently shown region:

import cartopy.feature as cfeature

fig = plt.figure()

# Set projection
ax = plt.axes(projection=cartopy.crs.PlateCarree())

# Re-aspect plot (only for plain matplotlib plots, or when using PlateCarree)
LATKM = 110.574
lat_region = <approximate latitude at the center of the plot>
ax.set_aspect(1 / (LATKM / 111.320 * np.cos(np.deg2rad(lat_region)))) 

ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.COASTLINE, ...)
ax.coastlines(resolution='50m', ...)
ax.add_feature(cfeature.BORDERS, ...)

ax.scatter(...)

(Note that you don't need to specify the transform=cartopy.crs.PlateCarree() argument in the plot/scatter/pcolor functions, but you can.)

I found this approach completely sufficient at country-level zoom levels (or closer). By setting the correct aspect ratio at the current latitude, you'll hardly notice a difference to projection-based plots at such zoom levels (unless you plot larger countries like Russia, etc. 😉). Plotting is also faster (~2-3x), as it avoids using more expensive transform objects (such as Mercator(), Orthographic(), you name it); note that this speed increase is independent of the number of plotted events / grid cells. (Btw: In case you want to benchmark the plotting speed, be aware that cartopy uses some sort of memoizing, so you need to reload the module every time.)

Suggested "fix": Maybe we can implement an intelligent switch (and/or an arg) to use plain PlateCaree + set_aspect. Essentially, this would need to happen in csep.utils.plots.plot_basemap.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions