def field_variable(ds, var, time, idx=None): """TODO: Docstring for field_variable. :ds: TODO :var: TODO :time: TODO :idx: TODO :returns: TODO """ try: ds = ds.rename({'globalx': 'x', 'globaly': 'y'}) except ValueError: pass if idx is not None: try: data = ds[var][idx, :, :] except IndexError as e: print(e) raise else: try: data = ds[var].isel(time=time) except IndexError as e: print(e) raise try: x = ds.x.values y = ds.y.values xmin = x[x != 0].min() xmax = x[x != 0].max() ymin = y[y != 0].min() ymax = y[y != 0].max() xc = (xmax + xmin) / 2 yc = (ymax + ymin) / 2 except AttributeError as e: print("Coordinates are not labeled (x, y)") print(e) pass fig, ax = subplots( figsize=(24, 9), subplot_kw={"projection": ccrs.TransverseMercator(xc, yc)}) data.where(data.x != 0).plot.contourf( ax=ax, transform=ccrs.TransverseMercator(xc, yc), x="x", y="y", add_colorbar=True, levels=25, ) return fig, ax
def scale_bar(ax, location=(0.92, 0.95)): llx0, llx1, lly0, lly1 = ax.get_extent(ccrs.PlateCarree()) sbllx = (llx1 + llx0) / 2 sblly = lly0 + (lly1 - lly0) * location[1] tmc = ccrs.TransverseMercator(sbllx, sblly) x0, x1, y0, y1 = ax.get_extent(tmc) sbx = x0 + (x1 - x0) * location[0] sby = y0 + (y1 - y0) * location[1] plt.plot([sbx, sbx - 20000], [sby, sby], color='k', linewidth=9, transform=tmc) plt.plot([sbx, sbx - 10000], [sby, sby], color='k', linewidth=6, transform=tmc) plt.plot([sbx - 10000, sbx - 20000], [sby, sby], color='w', linewidth=6, transform=tmc) plt.text(sbx, sby - 4500, '20 km', transform=tmc, fontsize=8) plt.text(sbx - 12500, sby - 4500, '10 km', transform=tmc, fontsize=8) plt.text(sbx - 24500, sby - 4500, '0 km', transform=tmc, fontsize=8)
def test_out_of_bounds(self): # Check that a ring that is completely out of the map boundary # produces an empty result. # XXX Check efficiency? projection = ccrs.TransverseMercator(central_longitude=0, approx=True) rings = [ # All valid ([(86, 1), (86, -1), (88, -1), (88, 1)], -1), # One NaN ([(86, 1), (86, -1), (130, -1), (88, 1)], 1), # A NaN segment ([(86, 1), (86, -1), (130, -1), (130, 1)], 1), # All NaN ([(120, 1), (120, -1), (130, -1), (130, 1)], 0), ] # Try all four combinations of valid/NaN vs valid/NaN. for coords, expected_n_lines in rings: linear_ring = sgeom.LinearRing(coords) rings, mlinestr = projection.project_geometry(linear_ring) if expected_n_lines == -1: assert rings assert not mlinestr else: assert len(mlinestr) == expected_n_lines if expected_n_lines == 0: assert mlinestr.is_empty
def test_out_of_bounds(self): # Check that a ring that is completely out of the map boundary # produces an empty result. # XXX Check efficiency? projection = ccrs.TransverseMercator(central_longitude=0) rings = [ # All valid ([(86, 1), (86, -1), (88, -1), (88, 1)], -1), # One NaN ([(86, 1), (86, -1), (130, -1), (88, 1)], 1), # A NaN segment ([(86, 1), (86, -1), (130, -1), (130, 1)], 1), # All NaN ([(120, 1), (120, -1), (130, -1), (130, 1)], 0), ] # Try all four combinations of valid/NaN vs valid/NaN. for coords, expected_n_lines in rings: linear_ring = geometry.polygon.LinearRing(coords) projected = projection.project_geometry(linear_ring) if expected_n_lines == -1: self.assertIsInstance(projected, geometry.polygon.LinearRing) else: self.assertEqual(len(projected), expected_n_lines) if expected_n_lines == 0: self.assertTrue(projected.is_empty)
def scale_bar(ax, length=100, location=(0.5, 0.05), linewidth=3): """Draw a scale bar Adapted from https://stackoverflow.com/questions/32333870/how-can-i-show-a-km-ruler-on-a-cartopy-matplotlib-plot/35705477#35705477 Parameters ---------- ax : axes length : int length of the scalebar in km. location: tuple center of the scalebar in axis coordinates (ie. 0.5 is the middle of the plot) linewidth: float thickness of the scalebar. """ # lat-lon limits llx0, llx1, lly0, lly1 = ax.get_extent(ccrs.PlateCarree()) # Transverse mercator for length x = (llx1 + llx0) / 2 y = lly0 + (lly1 - lly0) * location[1] tmc = ccrs.TransverseMercator(x, y) # Extent of the plotted area in coordinates in metres x0, x1, y0, y1 = ax.get_extent(tmc) # Scalebar location coordinates in metres sbx = x0 + (x1 - x0) * location[0] sby = y0 + (y1 - y0) * location[1] bar_xs = [sbx - length * 500, sbx + length * 500] # Plot the scalebar and label ax.plot(bar_xs, [sby, sby], transform=tmc, color='k', linewidth=linewidth) ax.text(sbx, sby + 10*length, str(length) + ' km', transform=tmc, horizontalalignment='center', verticalalignment='bottom')
def test_as_cartopy_projection(self): latitude_of_projection_origin = 49.0 longitude_of_central_meridian = -2.0 false_easting = -40000.0 false_northing = 10000.0 scale_factor_at_central_meridian = 0.9996012717 ellipsoid = GeogCS(semi_major_axis=6377563.396, semi_minor_axis=6356256.909) tmerc_cs = TransverseMercator( latitude_of_projection_origin, longitude_of_central_meridian, false_easting, false_northing, scale_factor_at_central_meridian, ellipsoid=ellipsoid, ) expected = ccrs.TransverseMercator( central_longitude=longitude_of_central_meridian, central_latitude=latitude_of_projection_origin, false_easting=false_easting, false_northing=false_northing, scale_factor=scale_factor_at_central_meridian, globe=ccrs.Globe( semimajor_axis=6377563.396, semiminor_axis=6356256.909, ellipse=None, ), ) res = tmerc_cs.as_cartopy_projection() self.assertEqual(res, expected)
def different_projection(self, method, ancillary_data, additional_data, expected, **kwargs): """Test that the plugin copes with non-lat/lon grids.""" src_crs = ccrs.PlateCarree() trg_crs = ccrs.TransverseMercator(central_latitude=0, central_longitude=0) trg_crs_iris = coord_systems.TransverseMercator(0, 0, 0, 0, 1.0) lons = [-50, 50] lats = [-25, 25] x, y = [], [] for lon, lat in zip(lons, lats): x_trg, y_trg = trg_crs.transform_point(lon, lat, src_crs) x.append(x_trg) y.append(y_trg) new_x = DimCoord(np.linspace(x[0], x[1], 20), standard_name='projection_x_coordinate', units='m', coord_system=trg_crs_iris) new_y = DimCoord(np.linspace(y[0], y[1], 20), standard_name='projection_y_coordinate', units='m', coord_system=trg_crs_iris) new_cube = Cube(np.zeros(400).reshape(20, 20), long_name="air_temperature", dim_coords_and_dims=[(new_y, 0), (new_x, 1)], units="K") cube = self.cube.copy() cube = cube.regrid(new_cube, iris.analysis.Nearest()) if ancillary_data is not None: ancillary_data['orography'] = ancillary_data['orography'].regrid( new_cube, iris.analysis.Nearest()) if additional_data is not None: for ad in additional_data.keys(): additional_data[ad] = additional_data[ad].regrid( new_cube, iris.analysis.Nearest()) # Define neighbours on this new projection self.neighbour_list['i'] = 11 self.neighbour_list['j'] = 11 plugin = Plugin(method) with iris.FUTURE.context(cell_datetime_objects=True): cube = cube.extract(self.time_extract) result = plugin.process(cube, self.sites, self.neighbour_list, ancillary_data, additional_data, **kwargs) self.assertEqual(cube.coord_system(), trg_crs_iris) self.assertAlmostEqual(result.data, expected) self.assertEqual(result.coord(axis='y').name(), 'latitude') self.assertEqual(result.coord(axis='x').name(), 'longitude') self.assertAlmostEqual(result.coord(axis='y').points, 4.74) self.assertAlmostEqual(result.coord(axis='x').points, 9.47)
def test_nan(self, approx): if not approx: pytest.xfail('Proj does not return NaN correctly with etmerc.') proj = ccrs.TransverseMercator(approx=approx) res = proj.transform_point(0.0, float('nan'), src_crs=self.src_crs) assert np.all(np.isnan(res)) res = proj.transform_point(float('nan'), 0.0, src_crs=self.src_crs) assert np.all(np.isnan(res))
def test_nan_start(self): projection = ccrs.TransverseMercator(central_longitude=-90) line_string = geometry.LineString([(10, 50), (-10, 30)]) multi_line_string = projection.project_geometry(line_string) self.assertEqual(len(multi_line_string), 1) for line_string in multi_line_string: for coord in line_string.coords: self.assertFalse(any(numpy.isnan(coord)), 'Unexpected NaN in projected coords.')
def test_default(self): proj = ccrs.TransverseMercator() res = proj.transform_point(*self.point_a, src_crs=self.src_crs) np.testing.assert_array_almost_equal( res, (-245269.53180633, 5627508.74354959)) res = proj.transform_point(*self.point_b, src_crs=self.src_crs) np.testing.assert_array_almost_equal( res, (35474.63566645, 5596583.41949901))
def test_misc(self): projection = ccrs.TransverseMercator(central_longitude=-90) line_string = geometry.LineString([(10, 50), (-10, 30)]) multi_line_string = projection.project_geometry(line_string) from cartopy.tests import show #show(projection, multi_line_string) for line_string in multi_line_string: for coord in line_string.coords: self.assertFalse(any(numpy.isnan(coord)), 'Unexpected NaN in projected coords.')
def test_nan_start(self): projection = ccrs.TransverseMercator(central_longitude=-90) line_string = sgeom.LineString([(10, 50), (-10, 30)]) multi_line_string = projection.project_geometry(line_string) assert len(multi_line_string) == 1 for line_string in multi_line_string: for coord in line_string.coords: assert not any(np.isnan(coord)), \ 'Unexpected NaN in projected coords.'
def test_default(self, approx): proj = ccrs.TransverseMercator(approx=approx) res = proj.transform_point(*self.point_a, src_crs=self.src_crs) np.testing.assert_array_almost_equal(res, (-245269.53181, 5627508.74355), decimal=5) res = proj.transform_point(*self.point_b, src_crs=self.src_crs) np.testing.assert_array_almost_equal(res, (35474.63566645, 5596583.41949901))
def as_cartopy_crs(self): globe = self._ellipsoid_to_globe(self.ellipsoid, None) return ccrs.TransverseMercator( central_longitude=self.longitude_of_central_meridian, central_latitude=self.latitude_of_projection_origin, false_easting=self.false_easting, false_northing=self.false_northing, scale_factor=self.scale_factor_at_central_meridian, globe=globe)
def test_misc(self): projection = ccrs.TransverseMercator(central_longitude=-90, approx=False) line_string = sgeom.LineString([(10, 50), (-10, 30)]) multi_line_string = projection.project_geometry(line_string) # from cartopy.tests.mpl import show # show(projection, multi_line_string) for line_string in multi_line_string: for coord in line_string.coords: assert not any(np.isnan(coord)), \ 'Unexpected NaN in projected coords.'
def test_nan_end(self): projection = ccrs.TransverseMercator(central_longitude=-90) line_string = sgeom.LineString([(-10, 30), (10, 50)]) multi_line_string = projection.project_geometry(line_string) # from cartopy.tests.mpl import show # show(projection, multi_line_string) self.assertEqual(len(multi_line_string), 1) for line_string in multi_line_string: for coord in line_string.coords: self.assertFalse(any(np.isnan(coord)), 'Unexpected NaN in projected coords.')
def _add_scale_bar(self, ax, length=None, location=(0.9, 0.05), linewidth=3): """ Adds scale bar to the image. Args: ax : axes to draw the scalebar on. length : length of the scalebar in km location : center of the scalebar in axis coordinates. (ie. 0.5 is the middle of the plot) linewidth : thickness of the scalebar. """ llx0, llx1, lly0, lly1 = ax.get_extent(ccrs.PlateCarree()) sbllx = (llx1 + llx0) / 2 sblly = lly0 + (lly1 - lly0) * location[1] tmc = ccrs.TransverseMercator(sbllx, sblly) x0, x1, y0, y1 = ax.get_extent(tmc) sbx = x0 + (x1 - x0) * location[0] sby = y0 + (y1 - y0) * location[1] if not length: length = (x1 - x0) / 5000 # in km ndim = int(np.floor( np.log10(length))) # number of digits in number length = round(length, -ndim) # round to 1sf def scale_number(x): if str(x)[0] in ['1', '2', '5']: return int(x) else: return scale_number(x - 10**ndim) length = scale_number(length) bar_xs = [sbx - length * 500, sbx + length * 500] ax.text(sbx, sby, str(length) + ' km', size=14, transform=tmc, horizontalalignment='center', color='k', verticalalignment='bottom') ax.plot(bar_xs, [sby, sby], transform=tmc, color='k', linewidth=linewidth)
def test_osgb_vals(self): proj = ccrs.TransverseMercator(central_longitude=-2, central_latitude=49, scale_factor=0.9996012717, false_easting=400000, false_northing=-100000, globe=ccrs.Globe(datum='OSGB36', ellipse='airy')) res = proj.transform_point(*self.point_a, src_crs=self.src_crs) np.testing.assert_array_almost_equal(res, (295971.28667707, 93064.27666368)) res = proj.transform_point(*self.point_b, src_crs=self.src_crs) np.testing.assert_array_almost_equal(res, (577274.98380140, 69740.49227181))
def test_set_xyticks(): fig = plt.figure(figsize=(10, 10)) projections = (ccrs.PlateCarree(), ccrs.Mercator(), ccrs.TransverseMercator(approx=False)) x = -3.275024 y = 50.753998 for i, prj in enumerate(projections, 1): ax = fig.add_subplot(3, 1, i, projection=prj) ax.set_extent([-12.5, 4, 49, 60], ccrs.Geodetic()) ax.coastlines('110m') p, q = prj.transform_point(x, y, ccrs.Geodetic()) ax.set_xticks([p]) ax.set_yticks([q]) return fig
def get_projection(extent=(-74.04, -52.90, -20.29, -57.38), epsg=None): """Get map axes Default to Argentina extent // Lambert Conformal projection """ if epsg is not None: ax_proj = ccrs.epsg(epsg) else: x0, x1, y0, y1 = extent cx = x0 + ((x1 - x0) / 2) cy = y0 + ((y1 - y0) / 2) ax_proj = ccrs.TransverseMercator(central_longitude=cx, central_latitude=cy) return ax_proj
def scale_bar(ax, length=None, location=(0.5, 0.05), linewidth=3): """ ax is the axes to draw the scalebar on. length is the length of the scalebar in km. location is center of the scalebar in axis coordinates. (ie. 0.5 is the middle of the plot) linewidth is the thickness of the scalebar. credits to https://stackoverflow.com/users/4278282/siyh """ #Get the limits of the axis in lat long llx0, llx1, lly0, lly1 = ax.get_extent(ccrs.PlateCarree()) #Make tmc horizontally centred on the middle of the map, #vertically at scale bar location sbllx = (llx1 + llx0) / 2 sblly = lly0 + (lly1 - lly0) * location[1] tmc = ccrs.TransverseMercator(sbllx, sblly) #Get the extent of the plotted area in coordinates in metres x0, x1, y0, y1 = ax.get_extent(tmc) #Turn the specified scalebar location into coordinates in metres sbx = x0 + (x1 - x0) * location[0] sby = y0 + (y1 - y0) * location[1] #Calculate a scale bar length if none has been given #(Theres probably a more pythonic way of rounding the number but this works) if not length: length = (x1 - x0) / 5000 #in km ndim = int(np.floor(np.log10(length))) #number of digits in number length = round(length, -ndim) #round to 1sf #Returns numbers starting with the list def scale_number(x): if str(x)[0] in ['1', '2', '5']: return int(x) else: return scale_number(x - 10**ndim) length = scale_number(length) #Generate the x coordinate for the ends of the scalebar bar_xs = [sbx - length * 500, sbx + length * 500] #Plot the scalebar ax.plot(bar_xs, [sby, sby], transform=tmc, color='k', linewidth=linewidth) #Plot the scalebar label ax.text(sbx, sby, str(length) + ' km', transform=tmc, horizontalalignment='center', verticalalignment='bottom')
def test_multiple_projections(): projections = [ ccrs.PlateCarree(), ccrs.Robinson(), ccrs.RotatedPole(pole_latitude=45, pole_longitude=180), ccrs.OSGB(), ccrs.TransverseMercator(), ccrs.Mercator(globe=ccrs.Globe(semimajor_axis=math.degrees(1)), min_latitude=-85., max_latitude=85.), ccrs.LambertCylindrical(), ccrs.Miller(), ccrs.Gnomonic(), ccrs.Stereographic(), ccrs.NorthPolarStereo(), ccrs.SouthPolarStereo(), ccrs.Orthographic(), ccrs.Mollweide(), ccrs.InterruptedGoodeHomolosine(), ] if ccrs.PROJ4_VERSION < (5, 0, 0): # Produce the same sized image for old proj, to avoid having to replace # the image. If this figure is regenerated for both old and new proj, # then drop this condition. rows = 5 else: rows = np.ceil(len(projections) / 5) fig = plt.figure(figsize=(10, 2 * rows)) for i, prj in enumerate(projections, 1): ax = fig.add_subplot(rows, 5, i, projection=prj) ax.set_global() ax.coastlines() plt.plot(-0.08, 51.53, 'o', transform=ccrs.PlateCarree()) plt.plot([-0.08, 132], [51.53, 43.17], color='red', transform=ccrs.PlateCarree()) plt.plot([-0.08, 132], [51.53, 43.17], color='blue', transform=ccrs.Geodetic())
def test_multiple_projections(): projections = [ ccrs.PlateCarree(), ccrs.Robinson(), ccrs.RotatedPole(pole_latitude=45, pole_longitude=180), ccrs.OSGB(approx=True), ccrs.TransverseMercator(approx=True), ccrs.Mercator(globe=ccrs.Globe(semimajor_axis=math.degrees(1)), min_latitude=-85., max_latitude=85.), ccrs.LambertCylindrical(), ccrs.Miller(), ccrs.Gnomonic(), ccrs.Stereographic(), ccrs.NorthPolarStereo(), ccrs.SouthPolarStereo(), ccrs.Orthographic(), ccrs.Mollweide(), ccrs.InterruptedGoodeHomolosine(emphasis='land'), ccrs.EckertI(), ccrs.EckertII(), ccrs.EckertIII(), ccrs.EckertIV(), ccrs.EckertV(), ccrs.EckertVI(), ] rows = np.ceil(len(projections) / 5).astype(int) fig = plt.figure(figsize=(10, 2 * rows)) for i, prj in enumerate(projections, 1): ax = fig.add_subplot(rows, 5, i, projection=prj) ax.set_global() ax.coastlines(resolution="110m") plt.plot(-0.08, 51.53, 'o', transform=ccrs.PlateCarree()) plt.plot([-0.08, 132], [51.53, 43.17], color='red', transform=ccrs.PlateCarree()) plt.plot([-0.08, 132], [51.53, 43.17], color='blue', transform=ccrs.Geodetic())
def test_out_of_bounds(self): # Check that a line that is completely out of the map boundary produces # an empty result. # XXX Check efficiency? projection = ccrs.TransverseMercator(central_longitude=0) # For both start & end, define a point that results in well-defined # projection coordinates and one that results in NaN. start_points = [(86, 0), (130, 0)] end_points = [(88, 0), (120, 0)] # Try all four combinations of valid/NaN vs valid/NaN. for start, end in itertools.product(start_points, end_points): line_string = geometry.LineString([start, end]) multi_line_string = projection.project_geometry(line_string) self.assertEqual(len(multi_line_string), 0, 'Unexpected line when working from {} to {}'.format(start, end))
def test_out_of_bounds(self): # Check that a line that is completely out of the map boundary produces # a valid LineString projection = ccrs.TransverseMercator(central_longitude=0, approx=True) # For both start & end, define a point that results in well-defined # projection coordinates and one that results in NaN. start_points = [(86, 0), (130, 0)] end_points = [(88, 0), (120, 0)] # Try all four combinations of valid/NaN vs valid/NaN. for start, end in itertools.product(start_points, end_points): line_string = sgeom.LineString([start, end]) multi_line_string = projection.project_geometry(line_string) if start[0] == 130 and end[0] == 120: expected = 0 else: expected = 1 assert len(multi_line_string) == expected, \ 'Unexpected line when working from {} to {}'.format(start, end)
def get_axes(extent=(-74.04, -52.90, -20.29, -57.38), epsg=None): """Get map axes Default to Argentina extent // Lambert Conformal projection """ if epsg is not None: ax_proj = ccrs.epsg(epsg) else: x0, x1, y0, y1 = extent cx = x0 + ((x1 - x0) / 2) cy = y0 + ((y1 - y0) / 2) ax_proj = ccrs.TransverseMercator(central_longitude=cx, central_latitude=cy) print(" * Setup axes") plt.figure(figsize=(6, 10), dpi=300) ax = plt.axes([0.025, 0.025, 0.95, 0.95], projection=ax_proj) proj = ccrs.PlateCarree() ax.set_extent(extent, crs=proj) set_ax_bg(ax) return ax
def test_out_of_bounds(self): # Check that a polygon that is completely out of the map boundary # doesn't produce an empty result. projection = ccrs.TransverseMercator(central_longitude=0) polys = [ # All valid ([(86, -1), (86, 1), (88, 1), (88, -1)], 1), # One out of backwards projection range ([(86, -1), (86, 1), (130, 1), (88, -1)], 1), # An out of backwards projection range segment ([(86, -1), (86, 1), (130, 1), (130, -1)], 1), # All out of backwards projection range ([(120, -1), (120, 1), (130, 1), (130, -1)], 0), ] # Try all four combinations of valid/NaN vs valid/NaN. for coords, expected_polys in polys: polygon = Polygon(coords) multi_polygon = projection.project_geometry(polygon) self.assertEqual(len(multi_polygon), expected_polys)
def get_local_TransVerse_Mercator_Projection_for_given_geoaxes( ax, x_size_in_degrees): """ ax is the axes to draw the scalebar on. length is the length of the scalebar in km. location is center of the scalebar in axis coordinates. (ie. 0.5 is the middle of the plot) linewidth is the thickness of the scalebar. """ location = (0.5, 0.05) #Get the limits of the axis in lat long llx0, llx1, lly0, lly1 = ax.get_extent(ax.projection) #Make tmc horizontally centred on the middle of the map, #vertically at scale bar location sbllx = (llx1 + llx0) / 2 sblly = lly0 + (lly1 - lly0) * location[1] tmc = ccrs.TransverseMercator(sbllx, sblly) relative_ax_size = x_size_in_degrees / abs(llx1 - llx0) return tmc, relative_ax_size
def plot_shapefile(shp_file_base): shp = shapereader.Reader(shp_file_base) # transform = ccrs.PlateCarree() # We want the data plotted in UTM, and we will convert them to UTM before plotting # transform = ccrs.UTM(zone=16) transform = ccrs.TransverseMercator(central_longitude=-85, central_latitude=49, false_northing=5430000, false_easting=645000) fig = plt.figure(figsize=(12, 8)) # ax = fig.add_subplot(111) ax = plt.axes(projection=transform) ax.coastlines() for record, shape in zip(shp.records(), shp.geometries()): ax.add_geometries([shape], ccrs.PlateCarree(), facecolor='lightgrey', edgecolor='black', zorder=-1) for val, label in zip(ax.get_xticks(), ax.get_xticklabels()): label.set_text(str(val)) label.set_position((val, 0)) for val, label in zip(ax.get_yticks(), ax.get_yticklabels()): label.set_text(str(val)) label.set_position((0, val)) plt.tick_params(bottom=True, top=True, left=True, right=True, labelbottom=True, labeltop=False, labelleft=True, labelright=False) ax.xaxis.set_visible(True) ax.yaxis.set_visible(True) plt.grid(True) return fig
def test_multiple_projections(): projections = [ ccrs.PlateCarree(), ccrs.Robinson(), ccrs.RotatedPole(pole_latitude=45, pole_longitude=180), ccrs.OSGB(), ccrs.TransverseMercator(), ccrs.Mercator(globe=ccrs.Globe(semimajor_axis=math.degrees(1)), min_latitude=-85., max_latitude=85.), ccrs.LambertCylindrical(), ccrs.Miller(), ccrs.Gnomonic(), ccrs.Stereographic(), ccrs.NorthPolarStereo(), ccrs.SouthPolarStereo(), ccrs.Orthographic(), ccrs.Mollweide(), ccrs.InterruptedGoodeHomolosine(), ] fig = plt.figure(figsize=(10, 10)) for i, prj in enumerate(projections, 1): ax = fig.add_subplot(5, 5, i, projection=prj) ax.set_global() ax.coastlines() plt.plot(-0.08, 51.53, 'o', transform=ccrs.PlateCarree()) plt.plot([-0.08, 132], [51.53, 43.17], color='red', transform=ccrs.PlateCarree()) plt.plot([-0.08, 132], [51.53, 43.17], color='blue', transform=ccrs.Geodetic())