Manipulate projections (Halieutic dataset)¶
In [1]:
import gstlearn as gl
import gstlearn.plot as gp
import gstlearn.proj as prj
import gstlearn.document as gdoc
import matplotlib.pyplot as plt
import numpy as np
The ICES Working Group WGACEGG dataset: Acoustic Noise Scale (NASC) densities of anchovies and sardines per 1 nautical mile sampling unit, observed in spring 2018 and 2021.
Column descriptions:
- survey: campaign
- year: year
- time: date/time of data recording x: longitude in decimal degrees (WGS84)
- y: latitude in decimal degrees (WGS84)
- NASC: acoustic density in m².MN⁻²
- sp: species (anchovy = "ENGR-ENC"
- sardine = "SARD-PIL")
For more information on the origin of these data: Doray, M., Van Der Kooij, J., Boyra, G. (Eds.), 2021. ICES Survey Protocols - Manual for acoustic surveys coordinated under the ICES Working Group on Acoustic and Egg Surveys for Small Pelagic Fish (WGACEGG). https://doi.org/10.17895/ICES.PUB.7462.
Load the data in long/lat (alias WGS84 or EPSG:4326)
In [2]:
# Read the data
csv = csv = gl.CSVformat.create(True, charSep=";")
file_csv = gdoc.loadData("halieutic", "AC-SPRING-IBBB-NASC_ANE-PIL_2018-2021.csv")
data = gl.Db.createFromCSV(file_csv, csv=csv)
data.setLocators(["x", "y"], gl.ELoc.X)
data.setLocator("NASC", gl.ELoc.Z)
# Read the polygon
file_csv = gdoc.loadData("halieutic", "WGACEGGspringPolygon.csv")
poly = gl.Polygons.createFromCSV(file_csv, csv)
print("Polygon extension:", poly.getExtensionAsVD(), " degrees")
# Read the boundaries
name = gdoc.loadData("boundaries", "world.poly")
world = gl.Polygons.createFromNF(name)
print("Boundaries extension:", np.round(world.getExtensionAsVD(), 0), " degrees")
# Plot
fig, ax = gp.init(flagEqual=True)
ax.set_xlim([-15, 10])
ax.set_ylim([35, 52])
ax.symbol(data, s=1)
ax.polygon(poly)
ax.polygon(
world, edgecolor="black", facecolor="lightblue", flagFace=True, flagLabels=True
)
plt.show()
Polygon extension: [-9.94955409 -1.23270531 35.99409516 48.02438771] degrees Boundaries extension: [-180. 180. -90. 84.] degrees
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/backend_bases.py:2281, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs) 2277 try: 2278 # _get_renderer may change the figure dpi (as vector formats 2279 # force the figure dpi to 72), so we need to set it again here. 2280 with cbook._setattr_cm(self.figure, dpi=dpi): -> 2281 result = print_method( 2282 filename, 2283 facecolor=facecolor, 2284 edgecolor=edgecolor, 2285 orientation=orientation, 2286 bbox_inches_restore=_bbox_inches_restore, 2287 **kwargs) 2288 finally: 2289 if bbox_inches and restore_bbox: File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/backend_bases.py:2138, in FigureCanvasBase._switch_canvas_and_return_print_method.<locals>.<lambda>(*args, **kwargs) 2134 optional_kws = { # Passed by print_figure for other renderers. 2135 "dpi", "facecolor", "edgecolor", "orientation", 2136 "bbox_inches_restore"} 2137 skip = optional_kws - {*inspect.signature(meth).parameters} -> 2138 print_method = functools.wraps(meth)(lambda *args, **kwargs: meth( 2139 *args, **{k: v for k, v in kwargs.items() if k not in skip})) 2140 else: # Let third-parties do as they see fit. 2141 print_method = meth File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:537, in FigureCanvasAgg.print_png(self, filename_or_obj, metadata, pil_kwargs) 490 def print_png(self, filename_or_obj, *, metadata=None, pil_kwargs=None): 491 """ 492 Write the figure to a PNG file. 493 (...) 535 *metadata*, including the default 'Software' key. 536 """ --> 537 self._print_pil(filename_or_obj, "png", pil_kwargs, metadata) File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:485, in FigureCanvasAgg._print_pil(self, filename_or_obj, fmt, pil_kwargs, metadata) 480 def _print_pil(self, filename_or_obj, fmt, pil_kwargs, metadata=None): 481 """ 482 Draw the canvas, then save it using `.image.imsave` (to which 483 *pil_kwargs* and *metadata* are forwarded). 484 """ --> 485 FigureCanvasAgg.draw(self) 486 mpl.image.imsave( 487 filename_or_obj, self.buffer_rgba(), format=fmt, origin="upper", 488 dpi=self.figure.dpi, metadata=metadata, pil_kwargs=pil_kwargs) File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:438, in FigureCanvasAgg.draw(self) 435 # Acquire a lock on the shared font cache. 436 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar 437 else nullcontext()): --> 438 self.figure.draw(self.renderer) 439 # A GUI class may be need to update a window using this draw, so 440 # don't forget to call the superclass. 441 super().draw() File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs) 92 @wraps(draw) 93 def draw_wrapper(artist, renderer, *args, **kwargs): ---> 94 result = draw(artist, renderer, *args, **kwargs) 95 if renderer._rasterizing: 96 renderer.stop_rasterizing() File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer) 68 if artist.get_agg_filter() is not None: 69 renderer.start_filter() ---> 71 return draw(artist, renderer) 72 finally: 73 if artist.get_agg_filter() is not None: File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/figure.py:3282, in Figure.draw(self, renderer) 3279 # ValueError can occur when resizing a window. 3281 self.patch.draw(renderer) -> 3282 mimage._draw_list_compositing_images( 3283 renderer, self, artists, self.suppressComposite) 3285 renderer.close_group('figure') 3286 finally: File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/image.py:133, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite) 131 if not_composite or not has_images: 132 for a in artists: --> 133 a.draw(renderer) 134 else: 135 # Composite any adjacent images together 136 image_group = [] File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer) 68 if artist.get_agg_filter() is not None: 69 renderer.start_filter() ---> 71 return draw(artist, renderer) 72 finally: 73 if artist.get_agg_filter() is not None: File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/axes/_base.py:3350, in _AxesBase.draw(self, renderer) 3347 if artists_rasterized: 3348 _draw_rasterized(self.get_figure(root=True), artists_rasterized, renderer) -> 3350 mimage._draw_list_compositing_images( 3351 renderer, self, artists, self.get_figure(root=True).suppressComposite) 3353 renderer.close_group('axes') 3354 self.stale = False File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/image.py:133, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite) 131 if not_composite or not has_images: 132 for a in artists: --> 133 a.draw(renderer) 134 else: 135 # Composite any adjacent images together 136 image_group = [] File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer) 68 if artist.get_agg_filter() is not None: 69 renderer.start_filter() ---> 71 return draw(artist, renderer) 72 finally: 73 if artist.get_agg_filter() is not None: File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/text.py:909, in Text.draw(self, renderer) 905 textrenderer.draw_tex(gc, x, y, clean_line, 906 self._fontproperties, angle, 907 mtext=mtext) 908 else: --> 909 textrenderer.draw_text(gc, x, y, clean_line, 910 self._fontproperties, angle, 911 ismath=ismath, mtext=mtext) 913 gc.restore() 914 renderer.close_group('text') File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:245, in RendererAgg.draw_text(self, gc, x, y, s, prop, angle, ismath, mtext) 240 items = font._layout( 241 s, flags=get_hinting_flag(), 242 features=mtext.get_fontfeatures() if mtext is not None else None, 243 language=mtext.get_language() if mtext is not None else None) 244 size = prop.get_size_in_points() --> 245 self._draw_text_glyphs_and_boxes( 246 gc, x, y, angle, 247 ((item.ft_object, size, item.glyph_index, 0, 1, item.x, item.y) 248 for item in items), 249 []) File ~/work/gstlearn/gstlearn/.venv/lib/python3.14/site-packages/matplotlib/backends/backend_agg.py:182, in RendererAgg._draw_text_glyphs_and_boxes(self, gc, x, y, angle, glyphs, boxes) 180 for font, size, glyph_index, slant, extend, dx, dy in glyphs: # dy is upwards. 181 font.set_size(size, self.dpi) --> 182 font._set_transform( 183 (0x10000 * np.array([[cos, -sin], [sin, cos]]) 184 @ [[extend, extend * slant], [0, 1]]).round().astype(int), 185 [round(0x40 * (x + dx * cos - dy * sin)), 186 # FreeType's y is upwards. 187 round(0x40 * (self.height - y + dx * sin + dy * cos))] 188 ) 189 bitmap = font._render_glyph( 190 glyph_index, load_flags, 191 RenderMode.NORMAL if gc.get_antialiased() else RenderMode.MONO) 192 buffer = bitmap.buffer TypeError: _set_transform(): incompatible function arguments. The following argument types are supported: 1. (self: matplotlib.ft2font.FT2Font, matrix: typing.Annotated[collections.abc.Sequence[typing.Annotated[collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex], "FixedSize(2)"]], "FixedSize(2)"], delta: typing.Annotated[collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex], "FixedSize(2)"]) -> None Invoked with: <matplotlib.ft2font.FT2Font object at 0x7f5cf17c8670>, array([[65536, 0], [ 0, 65536]]), [522294613333328265084365694828544, -78766]
<Figure size 640x480 with 1 Axes>
Transform all coordinates to EPSG:2154 and display only some countries
In [3]:
crsFrom = "EPSG:4326" # WGS84 (lat/lon)
crsTo = "EPSG:2154"
# Transform the data coordinates
datat = data.clone()
x, y = prj.proj(datat["x"], datat["y"], crsFrom, crsTo)
datat["x"] = x
datat["y"] = y
# Transform polygon coordinates
polyt = poly.clone()
x, y = prj.proj(polyt.getX(0), polyt.getY(0), crsFrom, crsTo)
polyt.setX(0, x)
polyt.setY(0, y)
ext = polyt.getExtensionAsVD()
print("Polygon extension:", np.round(ext, 0), " meters")
# Transform boundaries coordinates (only for France, Portugal and Spain)
ids = [119, 214, 215]
worldt = gl.Polygons()
nid = 0
for id in ids:
worldt.addPolyElem(world.getPolyElem(id))
x, y = prj.proj(worldt.getX(nid), worldt.getY(nid), crsFrom, crsTo)
worldt.setX(nid, x)
worldt.setY(nid, y)
nid += 1
print("Boundaries extension:", np.round(worldt.getExtensionAsVD(), 0), " meters")
# Plot
fig, ax = gp.init(flagEqual=True)
ax.symbol(datat, s=1)
ax.polygon(polyt)
ax.polygon(
worldt,
edgecolor="black",
facecolor="lightblue",
flagFace=True,
flagLabels=True,
labels=["France", "Portugal", "Spain"],
)
plt.show()
Polygon extension: [-427232. 368841. 5479556. 6797888.] meters Boundaries extension: [-393135. 1072736. 5463375. 7117128.] meters
In [4]:
# Plot the two basemaps together from the initial data
fig, axs = gp.init(ny=2)
axs[0].baseMap(data, size=0.5)
axs[1].baseMap(data, size=0.5, flagProj=True, crsFrom=crsFrom, crsTo=crsTo)
plt.show()
In [ ]: