SpECTRE Documentation Coverage Report
Current view: top level - __w/spectre/spectre/build/docs/tmp/notebooks_md - VisualizationWithPython.md Hit Total Coverage
Commit: e1f22ede76131d2a431eabbd2dd32008f3162edb Lines: 0 1 0.0 %
Date: 2025-04-16 15:32:12
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : ## Visualization with Python {#tutorial_vis_python}
       2             : 
       3             : This tutorial shows you how to load 3D volume data in Python and visualize it
       4             : using `matplotlib`.
       5             : 
       6             : First, you need access to the `spectre` Python bindings. A simple way to do this
       7             : is to run a Jupyter server from the build directory:
       8             : 
       9             : ```sh
      10             : ./bin/python-spectre -m jupyterlab
      11             : ```
      12             : 
      13             : You can find detailed instruction in the tutorial on \ref spectre_using_python.
      14             : 
      15             : > Note for VSCode users: You can also select this Jupyter server as kernel for
      16             : > notebooks running in VSCode (see [docs](https://code.visualstudio.com/docs/datascience/jupyter-notebooks#_connect-to-a-remote-jupyter-server)).
      17             : 
      18             : Now we can import modules from the `spectre` Python package.
      19             : 
      20             : 
      21             : ```python
      22             : # Distributed under the MIT License.
      23             : # See LICENSE.txt for details.
      24             : 
      25             : import matplotlib.pyplot as plt
      26             : import numpy as np
      27             : import os
      28             : 
      29             : plt.style.use("../Examples/plots.mplstyle")
      30             : ```
      31             : 
      32             : ## Select an observation
      33             : 
      34             : First, we open the H5 volume data files from a simulation and get a list of all
      35             : available observations and their times:
      36             : 
      37             : 
      38             : ```python
      39             : from spectre.Visualization.OpenVolfiles import open_volfiles
      40             : from spectre.Visualization.ReadH5 import list_observations
      41             : import glob
      42             : 
      43             : h5files = glob.glob(
      44             :     # Point this to your volume data files
      45             :     "BbhVolume*.h5"
      46             : )
      47             : subfile_name = "/VolumeData"
      48             : obs_ids, obs_times = list_observations(open_volfiles(h5files, subfile_name))
      49             : ```
      50             : 
      51             : We can also list all available variables in the volume data files:
      52             : 
      53             : 
      54             : ```python
      55             : import rich.columns
      56             : 
      57             : for volfile in open_volfiles(h5files, subfile_name, obs_ids[-1]):
      58             :     all_vars = volfile.list_tensor_components(obs_ids[-1])
      59             :     # Only look into the first file. The other should have the same variables.
      60             :     break
      61             : 
      62             : rich.print(rich.columns.Columns(all_vars))
      63             : ```
      64             : 
      65             : 
      66             : <pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">ConformalFactor                 ExtrinsicCurvature_xx           ExtrinsicCurvature_yx          
      67             : ExtrinsicCurvature_yy           ExtrinsicCurvature_zx           ExtrinsicCurvature_zy          
      68             : ExtrinsicCurvature_zz           InertialCoordinates_x           InertialCoordinates_y          
      69             : InertialCoordinates_z           Lapse                           RadiallyCompressedCoordinates_x
      70             : RadiallyCompressedCoordinates_y RadiallyCompressedCoordinates_z ShiftExcess_x                  
      71             : ShiftExcess_y                   ShiftExcess_z                   Shift_x                        
      72             : Shift_y                         Shift_z                         SpatialMetric_xx               
      73             : SpatialMetric_yx                SpatialMetric_yy                SpatialMetric_zx               
      74             : SpatialMetric_zy                SpatialMetric_zz                                               
      75             : </pre>
      76             : 
      77             : 
      78             : 
      79             : ### Interpolate to a slice
      80             : 
      81             : One way of visualizing your 3D volume data in a 2D plot is with a slice. Use
      82             : `interpolate_to_points` to interpolate your volume data to any set of
      83             : coordinates:
      84             : 
      85             : 
      86             : ```python
      87             : from spectre.IO.Exporter import interpolate_to_points
      88             : 
      89             : # Coordinates of a regular grid in the xy plane
      90             : x, y = np.meshgrid(np.linspace(-15, 15, 300), np.linspace(-15, 15, 300))
      91             : z = np.zeros(x.shape)
      92             : 
      93             : # Interpolation can be slow, so it's useful to cache the result. Remember to
      94             : # delete the cache file if you change anything.
      95             : cache_file = "interpolated_data.npy"
      96             : if os.path.isfile(cache_file):
      97             :     lapse = np.load(cache_file)
      98             : else:
      99             :     lapse = np.array(
     100             :         interpolate_to_points(
     101             :             h5files,
     102             :             subfile_name=subfile_name,
     103             :             observation_id=obs_ids[-1],
     104             :             tensor_components=["Lapse"],
     105             :             target_points=[x.flatten(), y.flatten(), z.flatten()],
     106             :         )
     107             :     ).reshape(x.shape)
     108             :     np.save(cache_file, lapse)
     109             : ```
     110             : 
     111             : Now we can plot the 2D slice with `matplotlib`:
     112             : 
     113             : 
     114             : ```python
     115             : # Plot lapse
     116             : plt.contourf(x, y, np.log(1 - lapse))
     117             : 
     118             : # Plot circles for black holes
     119             : ax = plt.gca()
     120             : for bh_pos in [-8, 8]:
     121             :     ax.add_patch(
     122             :         plt.Circle(xy=(bh_pos, 0), radius=0.89, color="black", fill=True)
     123             :     )
     124             : 
     125             : # Make plot square
     126             : ax.set_aspect("equal")
     127             : ```
     128             : 
     129             :     /var/folders/xp/5t2ny359187c4ljckf8sz3m80000gn/T/ipykernel_19858/3375439396.py:2: RuntimeWarning: invalid value encountered in subtract
     130             :       plt.contourf(x, y, np.log(1 - lapse))
     131             : 
     132             : 
     133             : 
     134             :     
     135             : ![png](VisualizationWithPython_files/VisualizationWithPython_9_1.png)
     136             :     
     137             : 
     138             : 
     139             : ### Plot individual elements
     140             : 
     141             : You can also iterate over elements in your volume data to plot things like
     142             : element boundaries, collocation points, etc. Use `iter_elements`:
     143             : 
     144             : 
     145             : ```python
     146             : from spectre.IO.H5.IterElements import iter_elements
     147             : 
     148             : # Create a 3D plot
     149             : ax = plt.gcf().add_subplot(111, projection="3d")
     150             : ax.axis("off")
     151             : 
     152             : # Iterate over elements
     153             : for element in iter_elements(
     154             :     open_volfiles(h5files, subfile_name),
     155             :     obs_ids=obs_ids[0],
     156             :     element_patterns=["B3,*"],  # Only plot elements in block 3
     157             : ):
     158             :     # Draw outline of the element by mapping the edges of the logical cube to
     159             :     # inertial coordinates using the element map
     160             :     for d in range(3):
     161             :         for edge in range(4):
     162             :             line = np.zeros((3, 100))
     163             :             line[d, :] = np.linspace(-1, 1, 100)
     164             :             line[(d + 1) % 3, :] = 2 * (edge % 2) - 1
     165             :             line[(d + 2) % 3, :] = 2 * (edge // 2) - 1
     166             :             x, y, z = element.map(line)
     167             :             ax.plot(x, y, z, color="black")
     168             : 
     169             : # Make plot square
     170             : ax.set_aspect("equal")
     171             : ```
     172             : 
     173             : 
     174             :     
     175             : ![png](VisualizationWithPython_files/VisualizationWithPython_11_0.png)
     176             :     
     177             : 
     178             : 
     179             : 
     180             : ```python
     181             : 
     182             : ```

Generated by: LCOV version 1.14