plasma-plots 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. plasma_plots-0.1.0/LICENSE +16 -0
  2. plasma_plots-0.1.0/PKG-INFO +141 -0
  3. plasma_plots-0.1.0/README.md +96 -0
  4. plasma_plots-0.1.0/pyproject.toml +77 -0
  5. plasma_plots-0.1.0/setup.cfg +4 -0
  6. plasma_plots-0.1.0/src/plasma_plots/__init__.py +169 -0
  7. plasma_plots-0.1.0/src/plasma_plots/__main__.py +11 -0
  8. plasma_plots-0.1.0/src/plasma_plots/_api.py +317 -0
  9. plasma_plots-0.1.0/src/plasma_plots/_docs.py +266 -0
  10. plasma_plots-0.1.0/src/plasma_plots/accessors.py +4591 -0
  11. plasma_plots-0.1.0/src/plasma_plots/analysis.py +2276 -0
  12. plasma_plots-0.1.0/src/plasma_plots/arrays.py +569 -0
  13. plasma_plots-0.1.0/src/plasma_plots/cli.py +1162 -0
  14. plasma_plots-0.1.0/src/plasma_plots/desc.py +313 -0
  15. plasma_plots-0.1.0/src/plasma_plots/figures.py +277 -0
  16. plasma_plots-0.1.0/src/plasma_plots/gallery.py +775 -0
  17. plasma_plots-0.1.0/src/plasma_plots/gvec.py +225 -0
  18. plasma_plots-0.1.0/src/plasma_plots/mpi.py +177 -0
  19. plasma_plots-0.1.0/src/plasma_plots/output_accessors.py +807 -0
  20. plasma_plots-0.1.0/src/plasma_plots/plotly_backend.py +2097 -0
  21. plasma_plots-0.1.0/src/plasma_plots/plotting.py +5428 -0
  22. plasma_plots-0.1.0/src/plasma_plots/pyvista_plots.py +1292 -0
  23. plasma_plots-0.1.0/src/plasma_plots/spectral.py +1539 -0
  24. plasma_plots-0.1.0/src/plasma_plots/spectral_plots.py +947 -0
  25. plasma_plots-0.1.0/src/plasma_plots/theory/__init__.py +51 -0
  26. plasma_plots-0.1.0/src/plasma_plots/theory/exact.py +956 -0
  27. plasma_plots-0.1.0/src/plasma_plots/theory/kinetic.py +1148 -0
  28. plasma_plots-0.1.0/src/plasma_plots/theory/numerics.py +518 -0
  29. plasma_plots-0.1.0/src/plasma_plots/theory/orbits.py +584 -0
  30. plasma_plots-0.1.0/src/plasma_plots/theory/parameters.py +683 -0
  31. plasma_plots-0.1.0/src/plasma_plots/theory/special.py +174 -0
  32. plasma_plots-0.1.0/src/plasma_plots/theory/waves.py +1276 -0
  33. plasma_plots-0.1.0/src/plasma_plots.egg-info/PKG-INFO +141 -0
  34. plasma_plots-0.1.0/src/plasma_plots.egg-info/SOURCES.txt +73 -0
  35. plasma_plots-0.1.0/src/plasma_plots.egg-info/dependency_links.txt +1 -0
  36. plasma_plots-0.1.0/src/plasma_plots.egg-info/entry_points.txt +2 -0
  37. plasma_plots-0.1.0/src/plasma_plots.egg-info/requires.txt +32 -0
  38. plasma_plots-0.1.0/src/plasma_plots.egg-info/top_level.txt +1 -0
  39. plasma_plots-0.1.0/tests/test_accessor_pages.py +18 -0
  40. plasma_plots-0.1.0/tests/test_analysis_and_core_output.py +343 -0
  41. plasma_plots-0.1.0/tests/test_api_index.py +49 -0
  42. plasma_plots-0.1.0/tests/test_argument_fixes.py +191 -0
  43. plasma_plots-0.1.0/tests/test_cli.py +625 -0
  44. plasma_plots-0.1.0/tests/test_desc.py +205 -0
  45. plasma_plots-0.1.0/tests/test_dispersion_branches.py +95 -0
  46. plasma_plots-0.1.0/tests/test_docs_snippets.py +88 -0
  47. plasma_plots-0.1.0/tests/test_docstrings.py +126 -0
  48. plasma_plots-0.1.0/tests/test_energies_and_run_plots.py +359 -0
  49. plasma_plots-0.1.0/tests/test_example_helpers.py +428 -0
  50. plasma_plots-0.1.0/tests/test_example_tools.py +236 -0
  51. plasma_plots-0.1.0/tests/test_figures.py +153 -0
  52. plasma_plots-0.1.0/tests/test_gallery.py +127 -0
  53. plasma_plots-0.1.0/tests/test_gvec.py +406 -0
  54. plasma_plots-0.1.0/tests/test_import.py +35 -0
  55. plasma_plots-0.1.0/tests/test_mpi.py +132 -0
  56. plasma_plots-0.1.0/tests/test_orbit_classification_and_continuum.py +127 -0
  57. plasma_plots-0.1.0/tests/test_oscillations_and_coordinates.py +119 -0
  58. plasma_plots-0.1.0/tests/test_output_accessors.py +322 -0
  59. plasma_plots-0.1.0/tests/test_package_guide.py +97 -0
  60. plasma_plots-0.1.0/tests/test_plotly_backend.py +891 -0
  61. plasma_plots-0.1.0/tests/test_plotting.py +540 -0
  62. plasma_plots-0.1.0/tests/test_profile_plots.py +73 -0
  63. plasma_plots-0.1.0/tests/test_pyvista_plots.py +261 -0
  64. plasma_plots-0.1.0/tests/test_real_simulations.py +350 -0
  65. plasma_plots-0.1.0/tests/test_save_figure.py +107 -0
  66. plasma_plots-0.1.0/tests/test_spectral.py +204 -0
  67. plasma_plots-0.1.0/tests/test_spectral_tools.py +346 -0
  68. plasma_plots-0.1.0/tests/test_theory_doctests.py +19 -0
  69. plasma_plots-0.1.0/tests/test_theory_exact.py +469 -0
  70. plasma_plots-0.1.0/tests/test_theory_kinetic.py +362 -0
  71. plasma_plots-0.1.0/tests/test_theory_numerics.py +331 -0
  72. plasma_plots-0.1.0/tests/test_theory_orbits.py +282 -0
  73. plasma_plots-0.1.0/tests/test_theory_parameters.py +236 -0
  74. plasma_plots-0.1.0/tests/test_theory_special.py +48 -0
  75. plasma_plots-0.1.0/tests/test_theory_waves.py +536 -0
@@ -0,0 +1,16 @@
1
+ Copyright (c) 2019-2026, Struphy developers, Max Planck Institute for Plasma Physics
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
4
+ associated documentation files (the "Software"), to deal in the Software without restriction,
5
+ including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
6
+ and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
7
+ subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial
10
+ portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
13
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
14
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
15
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
16
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: plasma-plots
3
+ Version: 0.1.0
4
+ Summary: Plots and diagnostics of labeled xarray output from plasma simulations, such as Struphy
5
+ Author-email: Max Lindqvist <max.lindqvist@ipp.mpg.de>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/struphy-hub/plasma-plots
8
+ Project-URL: Repository, https://github.com/struphy-hub/plasma-plots
9
+ Project-URL: Documentation, https://struphy-hub.github.io/plasma-plots
10
+ Project-URL: Issues, https://github.com/struphy-hub/plasma-plots/issues
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Scientific/Engineering :: Visualization
16
+ Requires-Python: >=3.11
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: matplotlib
20
+ Requires-Dist: numpy
21
+ Requires-Dist: xarray
22
+ Requires-Dist: ipywidgets
23
+ Provides-Extra: netcdf
24
+ Requires-Dist: netCDF4; extra == "netcdf"
25
+ Provides-Extra: pyvista
26
+ Requires-Dist: pyvista; extra == "pyvista"
27
+ Requires-Dist: imageio; extra == "pyvista"
28
+ Provides-Extra: profiling
29
+ Requires-Dist: scope-profiler[pproc]; extra == "profiling"
30
+ Provides-Extra: plotly
31
+ Requires-Dist: plotly; extra == "plotly"
32
+ Requires-Dist: kaleido; extra == "plotly"
33
+ Provides-Extra: gallery
34
+ Requires-Dist: plotly; extra == "gallery"
35
+ Requires-Dist: kaleido; extra == "gallery"
36
+ Requires-Dist: scope-profiler[pproc]>=0.6.1; extra == "gallery"
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest; extra == "dev"
39
+ Requires-Dist: ruff; extra == "dev"
40
+ Requires-Dist: h5py; extra == "dev"
41
+ Requires-Dist: griffe; extra == "dev"
42
+ Provides-Extra: desc
43
+ Requires-Dist: desc-opt; extra == "desc"
44
+ Dynamic: license-file
45
+
46
+ # plasma-plots
47
+
48
+ Note: This library is 100% written by AI, I have literally not looked at a single line of code. So why should you trust it? You should trust it because of the following [LEAN 4 PROOF](https://gprivate.com/6m80q).
49
+
50
+ Plots and diagnostics of labeled xarray data from plasma simulations: the
51
+ output of [Struphy](https://github.com/struphy-hub/struphy), and of any code
52
+ whose arrays follow the same conventions (dimensions `t`, `eta1`/`eta2`/`eta3`,
53
+ mapped coordinates `X`/`Y`/`Z`, see
54
+ [Getting started](https://struphy-hub.github.io/plasma-plots/guides/getting-started/)).
55
+ It also reads [GVEC](https://gvec.readthedocs.io)'s equilibrium evaluations directly. It is a
56
+ separate package, so it can evolve and release independently of the Struphy runtime.
57
+
58
+ Full documentation: https://struphy-hub.github.io/plasma-plots
59
+
60
+ ## Installation
61
+
62
+ Python **3.11 or newer** is required; CI tests Python 3.11 and 3.12.
63
+ The base install plots in-memory xarray data. Install extras for file formats
64
+ and optional renderers:
65
+
66
+ ```bash
67
+ pip install plasma-plots
68
+ pip install "plasma-plots[netcdf]"
69
+ pip install "plasma-plots[netcdf,plotly]"
70
+ ```
71
+
72
+ | Extra | Enables | Dependencies |
73
+ | --- | --- | --- |
74
+ | `netcdf` | Read netCDF3/netCDF4 files through xarray and the CLI | `netCDF4` |
75
+ | `plotly` | Interactive browser plots and static Plotly exports | `plotly`, `kaleido` |
76
+ | `pyvista` | 3-D scenes and rendering | `pyvista`, `imageio` |
77
+ | `profiling` | Timing summaries and profiling plots | `scope-profiler[pproc]` |
78
+ | `desc` | Evaluate DESC equilibria | `desc-opt` |
79
+ | `gallery` | Export Struphy example-gallery figures and profiling | `plotly`, `kaleido`, `scope-profiler[pproc]>=0.6.1` |
80
+ | `dev` | Tests, linting and documentation tooling | `pytest`, `ruff`, `h5py`, `griffe` |
81
+
82
+ Struphy, GVEC and Zarr are separate installations; no extra above installs
83
+ them. Struphy users need the compatible output API described below. Install
84
+ `gvec` for GVEC evaluation or `zarr` to open Zarr stores. MP4 export requires
85
+ system `ffmpeg`; Matplotlib windows require a working GUI/display, and static
86
+ Plotly exports through Kaleido require a compatible Chrome installation.
87
+
88
+ For development, install with `pip install -e ".[dev]"`.
89
+
90
+ ## Struphy compatibility
91
+
92
+ Struphy integration is tested against commit
93
+ [`caddd229a3fcba1fada577d1af46d012e93d8b49`](https://github.com/struphy-hub/struphy/commit/caddd229a3fcba1fada577d1af46d012e93d8b49)
94
+ (the repository's pinned submodule, reporting version **3.3.0**). Use that
95
+ revision for a reproducible installation; compatibility with other Struphy
96
+ revisions, including older published builds, is not guaranteed. Struphy is
97
+ optional when working with ordinary xarray data.
98
+
99
+ ## Usage
100
+
101
+ Creating a Struphy `Output` loads plasma-plots, which registers `out.plot`,
102
+ `out.analysis` and the `.plasma` accessor on every product:
103
+
104
+ ```python
105
+ from struphy.post_processing.output import Output
106
+
107
+ out = Output("path/to/run")
108
+ out.evaluate("em_fields/phi").plasma.plot.slice(x="eta1", y="eta2", t=-1)
109
+ ```
110
+
111
+ > [!IMPORTANT]
112
+ > For xarray data that doesn't come from an `Output`, `import plasma_plots`
113
+ > first. Without it you get
114
+ > `AttributeError: 'DataArray' object has no attribute 'plasma'`.
115
+
116
+ In Python, `import plasma_plots; help(plasma_plots)` (or `plasma-plots guide` in a terminal) gives an overview,
117
+ printing an accessor lists its methods (`print(phi.plasma.plot)`), and `help()`
118
+ on a method shows every parameter. For language models and coding agents, the
119
+ documentation is available as plain text at
120
+ https://struphy-hub.github.io/plasma-plots/llms.txt. [API.md](API.md) (or
121
+ `plasma-plots api`) is a one-page index of every accessor method and function, and
122
+ [AGENTS.md](AGENTS.md) explains the code for agents working on it.
123
+
124
+ From the shell, the `plasma-plots` command saves figures of a Struphy run folder or a
125
+ netCDF file without any Python: `plasma-plots info sim_1`,
126
+ `plasma-plots plot sim_1 em_fields/phi slice t=-1 eta3=0 -o phi.png`,
127
+ `plasma-plots quicklook sim_1 -o figures/` (see the
128
+ [command-line guide](https://struphy-hub.github.io/plasma-plots/guides/command-line/)).
129
+
130
+ Direct plotting functions are available from
131
+ `plasma_plots.plotting`; analysis functions are in `plasma_plots.analysis`.
132
+
133
+ The accessor provides time-series, lineout, slice, panel, vector, comparison,
134
+ animation, and marker-trajectory plots. For three-dimensional scalar fields,
135
+ install the optional PyVista dependency (`pip install plasma-plots[pyvista]`) and
136
+ use `field.plasma.plot.volume(t=-1)`, then call `show()` on the returned plotter.
137
+
138
+ Every Matplotlib plot can also be an interactive Plotly figure, with hover values, zoom and,
139
+ for animations, a slider: `pip install plasma-plots[plotly]` and pass `backend="plotly"`
140
+ (`field.plasma.plot.slice(t=-1, backend="plotly")`), or call
141
+ `plasma_plots.set_backend("plotly")` once.
@@ -0,0 +1,96 @@
1
+ # plasma-plots
2
+
3
+ Note: This library is 100% written by AI, I have literally not looked at a single line of code. So why should you trust it? You should trust it because of the following [LEAN 4 PROOF](https://gprivate.com/6m80q).
4
+
5
+ Plots and diagnostics of labeled xarray data from plasma simulations: the
6
+ output of [Struphy](https://github.com/struphy-hub/struphy), and of any code
7
+ whose arrays follow the same conventions (dimensions `t`, `eta1`/`eta2`/`eta3`,
8
+ mapped coordinates `X`/`Y`/`Z`, see
9
+ [Getting started](https://struphy-hub.github.io/plasma-plots/guides/getting-started/)).
10
+ It also reads [GVEC](https://gvec.readthedocs.io)'s equilibrium evaluations directly. It is a
11
+ separate package, so it can evolve and release independently of the Struphy runtime.
12
+
13
+ Full documentation: https://struphy-hub.github.io/plasma-plots
14
+
15
+ ## Installation
16
+
17
+ Python **3.11 or newer** is required; CI tests Python 3.11 and 3.12.
18
+ The base install plots in-memory xarray data. Install extras for file formats
19
+ and optional renderers:
20
+
21
+ ```bash
22
+ pip install plasma-plots
23
+ pip install "plasma-plots[netcdf]"
24
+ pip install "plasma-plots[netcdf,plotly]"
25
+ ```
26
+
27
+ | Extra | Enables | Dependencies |
28
+ | --- | --- | --- |
29
+ | `netcdf` | Read netCDF3/netCDF4 files through xarray and the CLI | `netCDF4` |
30
+ | `plotly` | Interactive browser plots and static Plotly exports | `plotly`, `kaleido` |
31
+ | `pyvista` | 3-D scenes and rendering | `pyvista`, `imageio` |
32
+ | `profiling` | Timing summaries and profiling plots | `scope-profiler[pproc]` |
33
+ | `desc` | Evaluate DESC equilibria | `desc-opt` |
34
+ | `gallery` | Export Struphy example-gallery figures and profiling | `plotly`, `kaleido`, `scope-profiler[pproc]>=0.6.1` |
35
+ | `dev` | Tests, linting and documentation tooling | `pytest`, `ruff`, `h5py`, `griffe` |
36
+
37
+ Struphy, GVEC and Zarr are separate installations; no extra above installs
38
+ them. Struphy users need the compatible output API described below. Install
39
+ `gvec` for GVEC evaluation or `zarr` to open Zarr stores. MP4 export requires
40
+ system `ffmpeg`; Matplotlib windows require a working GUI/display, and static
41
+ Plotly exports through Kaleido require a compatible Chrome installation.
42
+
43
+ For development, install with `pip install -e ".[dev]"`.
44
+
45
+ ## Struphy compatibility
46
+
47
+ Struphy integration is tested against commit
48
+ [`caddd229a3fcba1fada577d1af46d012e93d8b49`](https://github.com/struphy-hub/struphy/commit/caddd229a3fcba1fada577d1af46d012e93d8b49)
49
+ (the repository's pinned submodule, reporting version **3.3.0**). Use that
50
+ revision for a reproducible installation; compatibility with other Struphy
51
+ revisions, including older published builds, is not guaranteed. Struphy is
52
+ optional when working with ordinary xarray data.
53
+
54
+ ## Usage
55
+
56
+ Creating a Struphy `Output` loads plasma-plots, which registers `out.plot`,
57
+ `out.analysis` and the `.plasma` accessor on every product:
58
+
59
+ ```python
60
+ from struphy.post_processing.output import Output
61
+
62
+ out = Output("path/to/run")
63
+ out.evaluate("em_fields/phi").plasma.plot.slice(x="eta1", y="eta2", t=-1)
64
+ ```
65
+
66
+ > [!IMPORTANT]
67
+ > For xarray data that doesn't come from an `Output`, `import plasma_plots`
68
+ > first. Without it you get
69
+ > `AttributeError: 'DataArray' object has no attribute 'plasma'`.
70
+
71
+ In Python, `import plasma_plots; help(plasma_plots)` (or `plasma-plots guide` in a terminal) gives an overview,
72
+ printing an accessor lists its methods (`print(phi.plasma.plot)`), and `help()`
73
+ on a method shows every parameter. For language models and coding agents, the
74
+ documentation is available as plain text at
75
+ https://struphy-hub.github.io/plasma-plots/llms.txt. [API.md](API.md) (or
76
+ `plasma-plots api`) is a one-page index of every accessor method and function, and
77
+ [AGENTS.md](AGENTS.md) explains the code for agents working on it.
78
+
79
+ From the shell, the `plasma-plots` command saves figures of a Struphy run folder or a
80
+ netCDF file without any Python: `plasma-plots info sim_1`,
81
+ `plasma-plots plot sim_1 em_fields/phi slice t=-1 eta3=0 -o phi.png`,
82
+ `plasma-plots quicklook sim_1 -o figures/` (see the
83
+ [command-line guide](https://struphy-hub.github.io/plasma-plots/guides/command-line/)).
84
+
85
+ Direct plotting functions are available from
86
+ `plasma_plots.plotting`; analysis functions are in `plasma_plots.analysis`.
87
+
88
+ The accessor provides time-series, lineout, slice, panel, vector, comparison,
89
+ animation, and marker-trajectory plots. For three-dimensional scalar fields,
90
+ install the optional PyVista dependency (`pip install plasma-plots[pyvista]`) and
91
+ use `field.plasma.plot.volume(t=-1)`, then call `show()` on the returned plotter.
92
+
93
+ Every Matplotlib plot can also be an interactive Plotly figure, with hover values, zoom and,
94
+ for animations, a slider: `pip install plasma-plots[plotly]` and pass `backend="plotly"`
95
+ (`field.plasma.plot.slice(t=-1, backend="plotly")`), or call
96
+ `plasma_plots.set_backend("plotly")` once.
@@ -0,0 +1,77 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "plasma-plots"
7
+ version = "0.1.0"
8
+ description = "Plots and diagnostics of labeled xarray output from plasma simulations, such as Struphy"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ authors = [{ name = "Max Lindqvist", email = "max.lindqvist@ipp.mpg.de" }]
12
+ requires-python = ">=3.11"
13
+ dependencies = ["matplotlib", "numpy", "xarray", "ipywidgets"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Science/Research",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Scientific/Engineering :: Visualization",
20
+ ]
21
+
22
+ [project.scripts]
23
+ plasma-plots = "plasma_plots.cli:main"
24
+
25
+ [project.optional-dependencies]
26
+ # Read netCDF3 and netCDF4 files through xarray (including the CLI).
27
+ netcdf = ["netCDF4"]
28
+ pyvista = ["pyvista", "imageio"]
29
+ profiling = ["scope-profiler[pproc]"]
30
+ # backend="plotly": interactive Plotly versions of the plots; kaleido saves them as PNG/SVG/PDF
31
+ plotly = ["plotly", "kaleido"]
32
+ # the output helpers of the struphy-hub example gallery (plasma_plots.gallery): Plotly figures,
33
+ # their static PNGs (kaleido) and the profiling export, which needs scope-profiler 0.6.1 or newer
34
+ gallery = ["plotly", "kaleido", "scope-profiler[pproc]>=0.6.1"]
35
+ dev = ["pytest", "ruff", "h5py", "griffe"]
36
+ # plasma_plots.from_desc: evaluating DESC equilibria (tests/test_desc.py, the DESC guide)
37
+ desc = ["desc-opt"]
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/struphy-hub/plasma-plots"
41
+ Repository = "https://github.com/struphy-hub/plasma-plots"
42
+ Documentation = "https://struphy-hub.github.io/plasma-plots"
43
+ Issues = "https://github.com/struphy-hub/plasma-plots/issues"
44
+
45
+ [tool.setuptools.packages.find]
46
+ where = ["src"]
47
+
48
+ [tool.pytest.ini_options]
49
+ # Restrict collection to our own tests: the struphy submodule now lives at
50
+ # ./struphy (with its own nested feectools submodule), and bare `pytest`
51
+ # would otherwise recurse into their test suites too -- and fail on their
52
+ # own optional dependencies (e.g. psydac) that plasma-plots has no need of.
53
+ testpaths = ["tests"]
54
+ # Real struphy simulations (compiled kernels, ~1 min): skipped unless requested with
55
+ # `pytest --run-simulations` (see tests/conftest.py); run in the docs workflow.
56
+ markers = ["simulation: runs a real struphy simulation; needs compiled kernels"]
57
+
58
+ [tool.ruff]
59
+ line-length = 120
60
+
61
+ [tool.ruff.lint]
62
+ select = ["E4", "E7", "E9", "F"]
63
+ ignore = [
64
+ "E265",
65
+ "E402",
66
+ "E701",
67
+ "E722",
68
+ "E731",
69
+ "E741",
70
+ "E742",
71
+ "E743",
72
+ "E902",
73
+ "F401",
74
+ "F403",
75
+ "F405",
76
+ "F841",
77
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,169 @@
1
+ """Plots and diagnostics of labeled xarray data from plasma simulations, such as Struphy's output.
2
+
3
+ plasma-plots adds accessors to the objects Struphy returns; you rarely call a function directly:
4
+
5
+ * ``out.plot`` and ``out.analysis`` on a Struphy ``Output``: whole-run plots and diagnostics.
6
+ * ``array.plasma.plot``, ``.analysis`` and ``.data`` on every ``xarray.DataArray``, e.g. a product
7
+ from ``out.evaluate("em_fields/phi")``.
8
+ * ``dataset.plasma.plot``, ``.analysis`` and ``.data`` on marker Datasets such as orbits.
9
+
10
+ Creating a Struphy ``Output`` loads plasma-plots, so its output needs no import. For xarray data
11
+ from elsewhere, ``import plasma_plots`` first; without it, ``.plasma`` raises
12
+ ``AttributeError: 'DataArray' object has no attribute 'plasma'``.
13
+
14
+ Printing an accessor lists its methods (``print(phi.plasma.plot)``), and ``help()`` on a method
15
+ shows every parameter (``help(phi.plasma.plot.slice)``). ``plasma-plots guide`` (or
16
+ ``python -m plasma_plots guide``) prints this guide, ``plasma-plots api`` an index of every method and
17
+ function with its signature. The ``plasma-plots`` command also saves figures from the shell, e.g.
18
+ ``plasma-plots plot sim_1 em_fields/phi slice t=-1 eta3=0 -o phi.png`` or
19
+ ``plasma-plots quicklook sim_1 -o figures/`` (``plasma-plots --help``).
20
+
21
+ A post-processing pipeline
22
+ --------------------------
23
+ >>> from struphy import Output # doctest: +SKIP
24
+ >>> out = Output("sim_1") # the run's output folder
25
+ >>> out.plot.energies().save("energies.png") # the energy budget and its drift
26
+ >>> # dims (t, eta1, eta2, eta3), coordinates X, Y, Z
27
+ >>> phi = out.evaluate("em_fields/phi")
28
+ >>> phi.plasma.plot.slice(coords="physical", plane="XY", t=-1, eta3=0).save(
29
+ ... "phi.png"
30
+ ... )
31
+ >>> phi.plasma.plot.animation(x="eta1", y="eta2", eta3=0).save(
32
+ ... "phi.gif", writer="pillow"
33
+ ... )
34
+ >>> # complex amplitudes over mode numbers m, n
35
+ >>> modes = phi.plasma.analysis.mode_spectrum()
36
+ >>> # the strongest (m, n) over time
37
+ >>> phi.plasma.plot.mode_amplitudes(top=4, fit=True)
38
+ >>> # guiding-center orbits, by orbit class
39
+ >>> out.kinetic_ions.orbits.plasma.plot.poloidal()
40
+
41
+ Selecting what to show
42
+ ----------------------
43
+ Name every dimension a plot doesn't draw: an integer is a position (``t=-1`` the last, ``t=0`` the
44
+ first) and a float the nearest coordinate value (``t=0.35``). Slices draw two dimensions: logical
45
+ ones (``x="eta1", y="eta2"``), or physical ones with ``coords="physical", plane="XY"`` (or
46
+ ``"XZ"``, ``"YZ"``, ``"RZ"``). ``array.plasma.data.<plot>(...)`` returns the selected data a plot
47
+ would draw, instead of the figure.
48
+
49
+ What is where
50
+ -------------
51
+ * Time series and rates: ``plot.timeseries(fit=(t0, t1), reference=...)``,
52
+ ``analysis.growth_rate``, ``analysis.damping_rate``, ``analysis.envelope``,
53
+ ``analysis.oscillation_frequency`` (from zero crossings).
54
+ * Profiles: ``plot.lineout``, ``plot.profiles``, ``plot.line_animation`` (``alongside=`` for
55
+ panels in sync), each with ``reference=`` for exact solutions; ``analysis.map_coordinate`` for
56
+ physical coordinates (``eta1`` → ``r`` in m).
57
+ * Several plots in one figure: ``with plasma_plots.figure(2, 1) as fig:`` and ``ax=fig[0]``,
58
+ ``ax=fig[1]``.
59
+ * 2-D fields: ``plot.slice``, ``plot.panels``, ``plot.animation``, ``plot.viewer``,
60
+ ``plot.frames``, with ``levels=`` (contour lines), ``overlays=`` (a second field's contours,
61
+ boundary, lines, points), ``symmetric=``, ``robust=``; ``plot.vector`` for vector fields.
62
+ * 3-D views (``pip install "plasma-plots[pyvista]"``): ``plot.isosurface``, ``plot.slices_3d``,
63
+ ``plot.glyphs``, ``plot.streamlines``, ``plot.movie``; ``data.to_vtk`` for ParaView.
64
+ * Spectra: ``analysis.time_fft``, ``analysis.spectral_peaks``, ``analysis.filter_time``,
65
+ ``analysis.mode_spectrum``, ``analysis.matrix_pencil``, ``analysis.cross_spectrum``;
66
+ ``plot.power_spectrum``, ``plot.spectrogram``, ``plot.mode_amplitudes``, ``plot.mode_profiles``.
67
+ * Dispersion relations: ``plot.dispersion(branches=...)``, ``analysis.dispersion`` and
68
+ ``.plasma.analysis.trace_branch(theory)`` on the spectrum.
69
+ * Comparing with theory: ``analysis.error(exact)``, ``plot.against_theory(theory)``,
70
+ ``analysis.project_mode``; convergence studies with ``plot.convergence``.
71
+ * Vector calculus on mapped domains: ``analysis.gradient``, ``analysis.divergence``,
72
+ ``analysis.curl``, ``analysis.flux_function``, ``analysis.toroidal_components``.
73
+ * Particles: ``dataset.plasma.plot.scatter``, ``.animation`` (``trail=``, ``paths=``,
74
+ ``color="classification"``), ``.paths``, ``.poloidal``,
75
+ ``.orbit_grid``, ``.orbit_classification``, ``.orbits_3d``; ``dataset.plasma.analysis.
76
+ classify_orbits``, ``.orbit_invariants``, ``.bounce_period``; binned distributions with
77
+ ``plot.slice(x="eta1", y="v1")`` and ``analysis.velocity_moments``.
78
+ * Whole runs: ``out.plot.energies``, ``out.plot.scalars``, ``out.plot.equilibrium``,
79
+ ``out.plot.profile``; ``out.analysis.linear_mhd_energies``, ``out.analysis.time_fft``,
80
+ ``out.analysis.mode_spectrum``.
81
+ * Integrals: ``plasma_plots.analysis.volume_integral`` and ``field_energy``;
82
+ ``analysis.surface_average`` for flux-surface averages.
83
+ * GVEC equilibria: ``.plasma`` reads ``state.evaluate(...)`` itself, ``plasma_plots.from_gvec(ds)``
84
+ attaches the geometry to every variable; poloidal planes with
85
+ ``overlays={"coordinate_lines": {"rho": 4, "theta_P": 8}}`` (and ``plane="X1X2"``), ι with
86
+ ``plot.lineout(rationals=4)`` and ``analysis.rational_surfaces``.
87
+ * DESC equilibria: ``plasma_plots.from_desc(eq, ["|B|", "iota", "sqrt(g)"], rho=11, theta=64,
88
+ zeta=40)`` evaluates them into the same flux-coordinate Datasets (``sfl="pest"`` for the PEST
89
+ angle ``theta_P``); DESC's names stay, ``ev["|B|"].plasma.plot...``.
90
+ * Analytic theory to compare with (plain functions, not accessors): ``plasma_plots.theory.kinetic``
91
+ (Landau damping, beam instabilities, Weibel), ``.waves`` (MHD, Hall-MHD and cold-plasma waves,
92
+ drift waves, continua), ``.parameters`` (plasma parameters, Struphy's units), ``.orbits``,
93
+ ``.exact`` (Riemann problem, dam break, diffusion, ...) and ``.numerics`` (time-integrator and
94
+ discretization errors). Their functions go straight into ``branches=``, ``reference=`` and
95
+ ``theory=``, e.g. ``phi.plasma.plot.dispersion(branches={"kinetic": kinetic.langmuir})``.
96
+
97
+ Plots return a ``PlotResult`` (``.fig``, ``.ax``, ``.save(path)``, ``.show()``); animations a
98
+ ``matplotlib.animation.FuncAnimation`` (keep a reference; ``.save("a.gif", writer="pillow")``); 3-D
99
+ views a ``pyvista.Plotter`` (``.show()``, ``.screenshot(path)``; ``pyvista.OFF_SCREEN = True`` in
100
+ scripts). Analysis methods return labeled xarray objects, which have ``.plasma`` in turn.
101
+
102
+ Every Matplotlib plot also draws as an interactive Plotly figure (``pip install
103
+ "plasma-plots[plotly]"``): ``phi.plasma.plot.slice(t=-1, eta3=0, backend="plotly")``, or
104
+ ``plasma_plots.set_backend("plotly")`` for all of them. The result is a ``PlotResult`` too
105
+ (``.save("phi.html")``); animations and viewers get a slider. See
106
+ :mod:`plasma_plots.plotly_backend`.
107
+
108
+ Under MPI (``mpirun -n 4 python script.py``), plots are drawn and saved on rank 0 only; the other
109
+ ranks get a ``SkippedPlot`` whose methods do nothing, so one script runs unchanged in serial and
110
+ in parallel. Analysis runs on every rank. See :mod:`plasma_plots.mpi`.
111
+
112
+ The functions behind the accessors, for plain ``xarray.DataArray`` input, are in
113
+ ``plasma_plots.plotting``, ``.analysis``, ``.spectral``, ``.spectral_plots``, ``.pyvista_plots``
114
+ and ``.arrays``.
115
+
116
+ Guides and the full reference: https://struphy-hub.github.io/plasma-plots (for language models:
117
+ https://struphy-hub.github.io/plasma-plots/llms.txt).
118
+
119
+ Example
120
+ -------
121
+ Runs as is, on synthetic data:
122
+
123
+ >>> import matplotlib
124
+ >>> matplotlib.use("Agg")
125
+ >>> import numpy as np
126
+ >>> import xarray as xr
127
+ >>> import plasma_plots
128
+ >>> t = np.linspace(0.0, 20.0, 201)
129
+ >>> x = np.linspace(0.0, 1.0, 64, endpoint=False)
130
+ >>> phi = xr.DataArray(
131
+ ... 0.01 * np.exp(0.1 * t)[:, None] * np.sin(2 * np.pi * x)[None],
132
+ ... dims=("t", "eta1"),
133
+ ... coords={"t": t, "eta1": x},
134
+ ... name="phi",
135
+ ... )
136
+ >>> # the k = 1 amplitude over t
137
+ >>> amplitude = phi.plasma.analysis.project_mode(dim="eta1", number=1)
138
+ >>> round(
139
+ ... float(amplitude.plasma.analysis.growth_rate(window=(5.0, 20.0)).rate),
140
+ ... 3,
141
+ ... )
142
+ 0.1
143
+ >>> result = phi.plasma.plot.slice(x="eta1", y="t") # a space-time map
144
+ >>> type(result).__name__
145
+ 'PlotResult'
146
+ """
147
+
148
+ from . import \
149
+ output_accessors # noqa: F401 (registers Output.plot, if struphy is installed)
150
+ from .accessors import PlasmaAccessor
151
+ from .desc import from_desc
152
+ from .figures import figure
153
+ from .gvec import from_gvec
154
+ from .mpi import SkippedPlot, is_plotting_rank, mpi_rank
155
+ from .plotly_backend import get_backend, set_backend
156
+ from .plotting import save_figure
157
+
158
+ __all__ = [
159
+ "SkippedPlot",
160
+ "PlasmaAccessor",
161
+ "figure",
162
+ "from_desc",
163
+ "from_gvec",
164
+ "get_backend",
165
+ "is_plotting_rank",
166
+ "mpi_rank",
167
+ "save_figure",
168
+ "set_backend",
169
+ ]
@@ -0,0 +1,11 @@
1
+ """``python -m plasma_plots``: the ``plasma-plots`` command (see :mod:`plasma_plots.cli`).
2
+
3
+ Without a command it prints the package guide (the same as ``help(plasma_plots)``);
4
+ ``python -m plasma_plots api`` prints the API index (see ``API.md``).
5
+ """
6
+
7
+ import sys
8
+
9
+ from plasma_plots.cli import main
10
+
11
+ sys.exit(main())