diff --git a/docs/configuration.ipynb b/docs/configuration.ipynb index da68d28f..512422cd 100644 --- a/docs/configuration.ipynb +++ b/docs/configuration.ipynb @@ -18,6 +18,7 @@ "- `\"select\"`: a cell selection criterion for selective loading\n", "- `\"cmap\"`: the default Matplotlib colormap to use\n", "- `\"render_mode\"`: the default rendering mode for figures (e.g. `\"image\"`, `\"contour\"`, `\"contourf\"`...)\n", + "- `\"sortby\"`: a dict of keys (e.g. `\"identity\"`) to be used for sorting data groups (`\"part\"`, `\"hydro\"`...) upon load. Set to `None` to disable sorting.\n", "\n", "## Additional units\n", "\n", @@ -76,7 +77,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -90,7 +91,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.1" + "version": "3.9.5" }, "nbsphinx": { "execute": "never" diff --git a/docs/index.rst b/docs/index.rst index a2cd1195..be992ab5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -104,6 +104,14 @@ Plotting: scatter plots plotting_scatter +Plotting: particles +=================== + +.. toctree:: + :maxdepth: 2 + + plotting_particles + Recipes ======= diff --git a/docs/plotting_particles.ipynb b/docs/plotting_particles.ipynb new file mode 100644 index 00000000..b9ac192e --- /dev/null +++ b/docs/plotting_particles.ipynb @@ -0,0 +1,198 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Plotting: particles\n", + "\n", + "In this notebook, we will load a cosmological simulation and visualize the dark matter particles within it.\n", + "\n", + "## A basic look at the particle positions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import osyris\n", + "\n", + "path = \"osyrisdata/cosmology\"\n", + "data = osyris.Dataset(100, scale=\"Mpc\", path=path).load('part')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We convert the particle masses to solar masses:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data['part']['mass'].to('msun')\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Having loaded the particle data,\n", + "we can quickly inspect the distribution of the particles by histogramming their `x` and `y` positions.\n", + "We use the particle mass as weights for the histogramming,\n", + "to give us a feel for how much mass is contained in one of the pixels of the image below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "osyris.histogram2d(data[\"part\"][\"position\"].x,\n", + " data[\"part\"][\"position\"].y,\n", + " data['part']['mass'],\n", + " resolution=512, norm=\"log\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sorting particles\n", + "\n", + "When particles are loaded, they are by default automatically sorted according to their `identity`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data[\"part\"][\"identity\"][:20].values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is possible to sort the `Datagroup` according to a new key,\n", + "if we wish for instance to sort the particles by AMR level.\n", + "This is achieved using the `.sortby()` method of the `Datagroup`.\n", + "It will sort all of the entries in a `Datagroup` according to one of the keys." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data[\"part\"][\"levelp\"][:20].values" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data[\"part\"].sortby(\"levelp\")\n", + "print(data[\"part\"][\"identity\"][:20].values)\n", + "print(data[\"part\"][\"levelp\"][:20].values)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The key which is chosen to automatically sort particles upon load is set inside the 'Parameters' of your [configuration file](configuration.ipynb).\n", + "A dict is defined to select one key per data group, e.g.\n", + "```\n", + "'sortby': {\n", + " 'part': 'identity'\n", + "}\n", + "```\n", + "To turn off any sorting, set `sortby` to `None`.\n", + "\n", + "## 3D rendering\n", + "\n", + "Osyris does not support 3D plotting out of the box,\n", + "but a 3D rendering of the particle positions in space can be achieved relatively easily in a Jupyter notebook using the `pythreejs` library." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "**Note**\n", + "\n", + "`pythreejs` is not a hard-dependency of Osyris. It needs to be installed separatey with `pip install pythreejs`.\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pythreejs as p3\n", + "\n", + "# Create a position buffer geometry\n", + "# Only plot one in 10 points to reduce the size of the output\n", + "geometry = p3.BufferGeometry(\n", + " attributes={\n", + " 'position': p3.BufferAttribute(\n", + " array=data[\"part\"][\"position\"][::10].values.astype('float32') - 75)\n", + " })\n", + "# Create a points material\n", + "material = p3.PointsMaterial(color='black', size=1)\n", + "# Combine the geometry and material into a Points object\n", + "points = p3.Points(geometry=geometry, material=material)\n", + "\n", + "# Create the scene and the renderer\n", + "view_width = 700\n", + "view_height = 500\n", + "camera = p3.PerspectiveCamera(position=[200.0, 0, 0], aspect=view_width/view_height)\n", + "scene = p3.Scene(children=[points, camera], background=\"#DDDDDD\")\n", + "controller = p3.OrbitControls(controlling=camera)\n", + "renderer = p3.Renderer(camera=camera, scene=scene, controls=[controller],\n", + " width=view_width, height=view_height)\n", + "renderer" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/requirements.txt b/docs/requirements.txt index 66c6c62e..4bed55e3 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -5,6 +5,7 @@ sphinx nbsphinx jupyter pint +pythreejs sphinx-copybutton sphinx-book-theme lic