|
17 | 17 | "\n", |
18 | 18 | "- [**Reading the output file**](#reading-the-output-file)\n", |
19 | 19 | "- [**Trajectory data structure**](#trajectory-data-structure)\n", |
20 | | - "- [**Analysis**](#analysis)\n", |
21 | | - "- [**Plotting**](#plotting)\n", |
| 20 | + "- [**Plotting**](#plotting-trajectories)\n", |
22 | 21 | "- [**Animations**](#animations)\n", |
23 | 22 | "\n", |
24 | 23 | "For more advanced reading and tutorials on the analysis of Lagrangian trajectories, we recommend checking out the [Lagrangian Diagnostics Analysis Cookbook](https://lagrangian-diags.readthedocs.io/en/latest/tutorials.html) and the project in general." |
|
77 | 76 | "npart = 10 # number of particles to be released\n", |
78 | 77 | "lon = 32 * np.ones(npart)\n", |
79 | 78 | "lat = np.linspace(-32.5, -30.5, npart, dtype=np.float32)\n", |
80 | | - "time = ds_fields.time.values[0] + np.arange(0, npart) * np.timedelta64(2, \"h\")\n", |
81 | 79 | "z = np.repeat(ds_fields.depth.values[0], npart)\n", |
| 80 | + "time = ds_fields.time.values[0] + np.arange(0, npart) * np.timedelta64(2, \"h\")\n", |
82 | 81 | "\n", |
83 | 82 | "pset = parcels.ParticleSet(\n", |
84 | | - " fieldset=fieldset, pclass=parcels.Particle, lon=lon, lat=lat, time=time, z=z\n", |
| 83 | + " fieldset=fieldset, pclass=parcels.Particle, x=lon, y=lat, z=z, time=time\n", |
85 | 84 | ")\n", |
86 | 85 | "\n", |
87 | 86 | "output_file = parcels.ParticleFile(\"output.parquet\", outputdt=np.timedelta64(2, \"h\"))" |
|
145 | 144 | "```{note}\n", |
146 | 145 | "As of Parcels v4, the default output format is [`parquet`](https://parquet.apache.org/) (instead of `zarr`). The `parquet` output format is a tabular format, in which every row corresponds to an observation of a particle trajectory. The `zarr` output format is a multidimensional array format, in which the data is stored in a 2D array with dimensions `traj` and `obs`. The `parquet` format is more compact and faster to read.\n", |
147 | 146 | "\n", |
148 | | - "However, the `parquet` format does not support the [CF-convention for trajectories data](http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#_multidimensional_array_representation_of_trajectories) implemented with the [NCEI trajectory template](https://www.ncei.noaa.gov/data/oceans/ncei/formats/netcdf/v2.0/trajectoryIncomplete.cdl). We are working on efficient tooling to convert the parcels `parquet` output into a CF-compliant format.\n", |
| 147 | + "However, the `parquet` format does not support the [CF-convention for trajectories data](http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#_multidimensional_array_representation_of_trajectories) implemented with the [NCEI trajectory template](https://www.ncei.noaa.gov/data/oceans/ncei/formats/netcdf/v2.0/trajectoryIncomplete.cdl). We have implemented a `parcels.read_particlefile()` function to facilitate reading `parquet` output files, see more information below.\n", |
149 | 148 | "\n", |
150 | | - "TODO: Add link to tracking issue on github for this tooling.\n", |
| 149 | + "TODO: Add information on conversion functions once https://github.com/Parcels-code/Parcels/issues/2600 is resolved.\n", |
151 | 150 | "```" |
152 | 151 | ] |
153 | 152 | }, |
|
263 | 262 | "outputs": [], |
264 | 263 | "source": [ |
265 | 264 | "fig, ax = plt.subplots(figsize=(5, 3))\n", |
266 | | - "ax.plot(df_particles[\"lon\"], df_particles[\"lat\"], \".-\")\n", |
| 265 | + "ax.plot(df_particles[\"x\"], df_particles[\"y\"], \".-\")\n", |
267 | 266 | "plt.show()" |
268 | 267 | ] |
269 | 268 | }, |
|
283 | 282 | "fig, ax = plt.subplots(figsize=(5, 3))\n", |
284 | 283 | "for traj in df_particles.partition_by(\"particle_id\", maintain_order=True):\n", |
285 | 284 | " traj_id = traj[\"particle_id\"][0]\n", |
286 | | - " ax.plot(traj[\"lon\"], traj[\"lat\"], \".-\", label=f\"P{traj_id}\")\n", |
| 285 | + " ax.plot(traj[\"x\"], traj[\"y\"], \".-\", label=f\"P{traj_id}\")\n", |
287 | 286 | "ax.legend(loc=\"center left\", bbox_to_anchor=(1.02, 0.5), borderaxespad=0.0)\n", |
288 | 287 | "plt.tight_layout()\n", |
289 | 288 | "plt.show()" |
|
307 | 306 | "particles = df_particles.filter(pl.col(\"time\") == pl.lit(time_to_plot))\n", |
308 | 307 | "\n", |
309 | 308 | "fig, ax = plt.subplots(figsize=(5, 3))\n", |
310 | | - "ax.plot(particles[\"lon\"], particles[\"lat\"], \"o\")\n", |
| 309 | + "ax.plot(particles[\"x\"], particles[\"y\"], \"o\")\n", |
311 | 310 | "title_time = pd.to_datetime(time_to_plot).strftime(\"%Y-%m-%d %H:%M:%S\")\n", |
312 | 311 | "ax.set_title(f\"Particle locations at {title_time}\")\n", |
313 | 312 | "plt.show()" |
|
332 | 331 | ")\n", |
333 | 332 | "\n", |
334 | 333 | "fig, ax = plt.subplots(figsize=(5, 3))\n", |
335 | | - "ax.plot(particles[\"lon\"], particles[\"lat\"], \"o\")\n", |
| 334 | + "ax.plot(particles[\"x\"], particles[\"y\"], \"o\")\n", |
336 | 335 | "ax.set_title(f\"Particle locations {time_step} after their release\")\n", |
337 | 336 | "plt.show()" |
338 | 337 | ] |
|
354 | 353 | "\n", |
355 | 354 | "for traj in df_particles.partition_by(\"particle_id\", maintain_order=True):\n", |
356 | 355 | " distance = np.sqrt(\n", |
357 | | - " (traj[\"lon\"] - traj[\"lon\"][0]) ** 2 + (traj[\"lat\"] - traj[\"lat\"][0]) ** 2\n", |
| 356 | + " (traj[\"x\"] - traj[\"x\"][0]) ** 2 + (traj[\"y\"] - traj[\"y\"][0]) ** 2\n", |
358 | 357 | " )\n", |
359 | 358 | " ax[0].plot(traj[\"time\"], distance, \".-\", label=f\"P{traj['particle_id'][0]}\")\n", |
360 | 359 | "\n", |
|
439 | 438 | "# --> plot first timestep\n", |
440 | 439 | "particles = df_particles.filter(pl.col(\"time\") == pl.lit(timerange[0]))\n", |
441 | 440 | "scatter = ax.scatter(\n", |
442 | | - " particles[\"lon\"],\n", |
443 | | - " particles[\"lat\"],\n", |
| 441 | + " particles[\"x\"],\n", |
| 442 | + " particles[\"y\"],\n", |
444 | 443 | " s=10,\n", |
445 | 444 | " c=[trajectory_to_color[p] for p in particles[\"particle_id\"]],\n", |
446 | 445 | ")\n", |
|
464 | 463 | " particles = df_particles.filter(pl.col(\"time\") == pl.lit(timerange[i]))\n", |
465 | 464 | "\n", |
466 | 465 | " if len(particles) > 0:\n", |
467 | | - " scatter.set_offsets(np.c_[particles[\"lon\"], particles[\"lat\"]])\n", |
| 466 | + " scatter.set_offsets(np.c_[particles[\"x\"], particles[\"y\"]])\n", |
468 | 467 | " scatter.set_color([trajectory_to_color[p] for p in particles[\"particle_id\"]])\n", |
469 | 468 | "\n", |
470 | 469 | " # --> reset trails\n", |
|
481 | 480 | " )\n", |
482 | 481 | " if len(traj_trail) > 1:\n", |
483 | 482 | " (trail,) = ax.plot(\n", |
484 | | - " traj_trail[\"lon\"],\n", |
485 | | - " traj_trail[\"lat\"],\n", |
| 483 | + " traj_trail[\"x\"],\n", |
| 484 | + " traj_trail[\"y\"],\n", |
486 | 485 | " color=trajectory_to_color[traj],\n", |
487 | 486 | " linewidth=0.6,\n", |
488 | 487 | " alpha=0.6,\n", |
|
502 | 501 | "metadata": { |
503 | 502 | "celltoolbar": "Metagegevens bewerken", |
504 | 503 | "kernelspec": { |
505 | | - "display_name": "docs", |
| 504 | + "display_name": "Parcels:docs (3.14.6)", |
506 | 505 | "language": "python", |
507 | 506 | "name": "python3" |
508 | 507 | }, |
|
516 | 515 | "name": "python", |
517 | 516 | "nbconvert_exporter": "python", |
518 | 517 | "pygments_lexer": "ipython3", |
519 | | - "version": "3.14.4" |
| 518 | + "version": "3.14.6" |
520 | 519 | } |
521 | 520 | }, |
522 | 521 | "nbformat": 4, |
|
0 commit comments