You can interact with this notebook online: Launch notebook

How to Generate a Last Interaction Velocity (LIV) Plot

The Last Interaction Velocity Plot tracks and display the velocities at which different elements (or species) last interacted with packets in the simulation.

First, create and run a simulation for which you want to generate this plot:

[1]:
from tardis import run_tardis
from tardis.io.atom_data import download_atom_data

# We download the atomic data needed to run the simulation
download_atom_data('kurucz_cd23_chianti_H_He')

sim = run_tardis("tardis_example.yml", virtual_packet_logging=True)
Atomic Data kurucz_cd23_chianti_H_He already exists in /home/runner/Downloads/tardis-data/kurucz_cd23_chianti_H_He.h5. Will not download - override with force_download=True.
[tardis.io.model.parse_atom_data][INFO   ]

        Reading Atomic Data from kurucz_cd23_chianti_H_He.h5 (parse_atom_data.py:40)
[tardis.io.atom_data.util][INFO   ]

        Atom Data kurucz_cd23_chianti_H_He.h5 not found in local path.
        Exists in TARDIS Data repo /home/runner/Downloads/tardis-data/kurucz_cd23_chianti_H_He.h5 (util.py:34)
[tardis.io.atom_data.base][INFO   ]
        Reading Atom Data with: UUID = 6f7b09e887a311e7a06b246e96350010 MD5  = 864f1753714343c41f99cb065710cace  (base.py:262)
[tardis.io.atom_data.base][INFO   ]
        Non provided Atomic Data: synpp_refs, photoionization_data, yg_data, two_photon_data, linelist_atoms, linelist_molecules (base.py:266)
[tardis.io.model.parse_density_configuration][WARNING]
        Number of density points larger than number of shells. Assuming inner point irrelevant (parse_density_configuration.py:114)
[tardis.model.matter.decay][INFO   ]
        Decaying abundances for 1123200.0 seconds (decay.py:101)
[tardis.simulation.base][INFO   ]

        Starting iteration 1 of 20 (base.py:450)
[py.warnings         ][WARNING]
        /home/runner/work/tardis/tardis/tardis/transport/montecarlo/montecarlo_main_loop.py:123: NumbaTypeSafetyWarning: unsafe cast from uint64 to int64. Precision may be lost.
  vpacket_collection = vpacket_collections[i]
 (warnings.py:112)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 7.942e+42 erg / s
        Luminosity absorbed  = 2.659e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 9.93e+03 K 1.01e+04 K 0.4 0.507
5 9.85e+03 K 1.02e+04 K 0.211 0.197
10 9.78e+03 K 1.01e+04 K 0.143 0.117
15 9.71e+03 K 9.87e+03 K 0.105 0.0869
[tardis.simulation.base][INFO   ]

        Current t_inner = 9933.952 K
        Expected t_inner for next iteration = 10703.212 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 2 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.071e+43 erg / s
        Luminosity absorbed  = 3.576e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.01e+04 K 1.08e+04 K 0.507 0.525
5 1.02e+04 K 1.1e+04 K 0.197 0.203
10 1.01e+04 K 1.08e+04 K 0.117 0.125
15 9.87e+03 K 1.05e+04 K 0.0869 0.0933
[tardis.simulation.base][INFO   ]

        Current t_inner = 10703.212 K
        Expected t_inner for next iteration = 10673.712 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 3 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.074e+43 erg / s
        Luminosity absorbed  = 3.391e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 1/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.08e+04 K 1.1e+04 K 0.525 0.483
5 1.1e+04 K 1.12e+04 K 0.203 0.189
10 1.08e+04 K 1.1e+04 K 0.125 0.118
15 1.05e+04 K 1.06e+04 K 0.0933 0.0895
[tardis.simulation.base][INFO   ]

        Current t_inner = 10673.712 K
        Expected t_inner for next iteration = 10635.953 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 4 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.058e+43 erg / s
        Luminosity absorbed  = 3.352e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 2/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.1e+04 K 0.483 0.469
5 1.12e+04 K 1.12e+04 K 0.189 0.182
10 1.1e+04 K 1.1e+04 K 0.118 0.113
15 1.06e+04 K 1.07e+04 K 0.0895 0.0861
[tardis.simulation.base][INFO   ]

        Current t_inner = 10635.953 K
        Expected t_inner for next iteration = 10638.407 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 5 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.055e+43 erg / s
        Luminosity absorbed  = 3.399e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 3/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.1e+04 K 0.469 0.479
5 1.12e+04 K 1.13e+04 K 0.182 0.178
10 1.1e+04 K 1.1e+04 K 0.113 0.113
15 1.07e+04 K 1.07e+04 K 0.0861 0.0839
[tardis.simulation.base][INFO   ]

        Current t_inner = 10638.407 K
        Expected t_inner for next iteration = 10650.202 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 6 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.061e+43 erg / s
        Luminosity absorbed  = 3.398e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 4/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.1e+04 K 0.479 0.47
5 1.13e+04 K 1.12e+04 K 0.178 0.185
10 1.1e+04 K 1.11e+04 K 0.113 0.112
15 1.07e+04 K 1.07e+04 K 0.0839 0.0856
[tardis.simulation.base][INFO   ]

        Current t_inner = 10650.202 K
        Expected t_inner for next iteration = 10645.955 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 7 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.061e+43 erg / s
        Luminosity absorbed  = 3.382e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 5/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.1e+04 K 0.47 0.47
5 1.12e+04 K 1.13e+04 K 0.185 0.178
10 1.11e+04 K 1.11e+04 K 0.112 0.112
15 1.07e+04 K 1.07e+04 K 0.0856 0.086
[tardis.simulation.base][INFO   ]

        Current t_inner = 10645.955 K
        Expected t_inner for next iteration = 10642.050 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 8 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.062e+43 erg / s
        Luminosity absorbed  = 3.350e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 6/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.11e+04 K 0.47 0.472
5 1.13e+04 K 1.14e+04 K 0.178 0.175
10 1.11e+04 K 1.11e+04 K 0.112 0.111
15 1.07e+04 K 1.07e+04 K 0.086 0.084
[tardis.simulation.base][INFO   ]

        Current t_inner = 10642.050 K
        Expected t_inner for next iteration = 10636.106 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 9 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.052e+43 erg / s
        Luminosity absorbed  = 3.411e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 7/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.11e+04 K 1.11e+04 K 0.472 0.469
5 1.14e+04 K 1.15e+04 K 0.175 0.17
10 1.11e+04 K 1.11e+04 K 0.111 0.109
15 1.07e+04 K 1.08e+04 K 0.084 0.0822
[tardis.simulation.base][INFO   ]

        Current t_inner = 10636.106 K
        Expected t_inner for next iteration = 10654.313 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 10 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.070e+43 erg / s
        Luminosity absorbed  = 3.335e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 8/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.11e+04 K 1.1e+04 K 0.469 0.475
5 1.15e+04 K 1.14e+04 K 0.17 0.177
10 1.11e+04 K 1.11e+04 K 0.109 0.112
15 1.08e+04 K 1.06e+04 K 0.0822 0.0878
[tardis.simulation.base][INFO   ]

        Current t_inner = 10654.313 K
        Expected t_inner for next iteration = 10628.190 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 11 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.053e+43 erg / s
        Luminosity absorbed  = 3.363e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 9/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.1e+04 K 0.475 0.472
5 1.14e+04 K 1.12e+04 K 0.177 0.184
10 1.11e+04 K 1.1e+04 K 0.112 0.114
15 1.06e+04 K 1.06e+04 K 0.0878 0.0859
[tardis.simulation.base][INFO   ]

        Current t_inner = 10628.190 K
        Expected t_inner for next iteration = 10644.054 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 12 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.056e+43 erg / s
        Luminosity absorbed  = 3.420e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 10/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.11e+04 K 0.472 0.467
5 1.12e+04 K 1.13e+04 K 0.184 0.176
10 1.1e+04 K 1.11e+04 K 0.114 0.11
15 1.06e+04 K 1.08e+04 K 0.0859 0.0821
[tardis.simulation.base][INFO   ]

        Current t_inner = 10644.054 K
        Expected t_inner for next iteration = 10653.543 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 13 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.062e+43 erg / s
        Luminosity absorbed  = 3.406e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 11/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.11e+04 K 1.11e+04 K 0.467 0.466
5 1.13e+04 K 1.13e+04 K 0.176 0.18
10 1.11e+04 K 1.11e+04 K 0.11 0.111
15 1.08e+04 K 1.08e+04 K 0.0821 0.0841
[tardis.simulation.base][INFO   ]

        Current t_inner = 10653.543 K
        Expected t_inner for next iteration = 10647.277 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 14 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.063e+43 erg / s
        Luminosity absorbed  = 3.369e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 12/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.11e+04 K 1.11e+04 K 0.466 0.469
5 1.13e+04 K 1.13e+04 K 0.18 0.182
10 1.11e+04 K 1.1e+04 K 0.111 0.113
15 1.08e+04 K 1.07e+04 K 0.0841 0.0854
[tardis.simulation.base][INFO   ]

        Current t_inner = 10647.277 K
        Expected t_inner for next iteration = 10638.875 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 15 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.053e+43 erg / s
        Luminosity absorbed  = 3.417e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 13/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.11e+04 K 1.1e+04 K 0.469 0.484
5 1.13e+04 K 1.13e+04 K 0.182 0.181
10 1.1e+04 K 1.1e+04 K 0.113 0.113
15 1.07e+04 K 1.07e+04 K 0.0854 0.0858
[tardis.simulation.base][INFO   ]

        Current t_inner = 10638.875 K
        Expected t_inner for next iteration = 10655.125 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 16 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.059e+43 erg / s
        Luminosity absorbed  = 3.445e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 14/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.1e+04 K 0.484 0.472
5 1.13e+04 K 1.13e+04 K 0.181 0.177
10 1.1e+04 K 1.1e+04 K 0.113 0.113
15 1.07e+04 K 1.06e+04 K 0.0858 0.0858
[tardis.simulation.base][INFO   ]

        Current t_inner = 10655.125 K
        Expected t_inner for next iteration = 10655.561 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 17 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.067e+43 erg / s
        Luminosity absorbed  = 3.372e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 15/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.1e+04 K 1.11e+04 K 0.472 0.468
5 1.13e+04 K 1.14e+04 K 0.177 0.175
10 1.1e+04 K 1.11e+04 K 0.113 0.11
15 1.06e+04 K 1.08e+04 K 0.0858 0.0816
[tardis.simulation.base][INFO   ]

        Current t_inner = 10655.561 K
        Expected t_inner for next iteration = 10636.536 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 18 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.057e+43 erg / s
        Luminosity absorbed  = 3.365e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 16/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.11e+04 K 1.11e+04 K 0.468 0.464
5 1.14e+04 K 1.13e+04 K 0.175 0.177
10 1.11e+04 K 1.1e+04 K 0.11 0.113
15 1.08e+04 K 1.07e+04 K 0.0816 0.0848
[tardis.simulation.base][INFO   ]

        Current t_inner = 10636.536 K
        Expected t_inner for next iteration = 10641.692 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Starting iteration 19 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.056e+43 erg / s
        Luminosity absorbed  = 3.405e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)
[tardis.simulation.base][INFO   ]
        Iteration converged 17/4 consecutive times. (base.py:262)
[tardis.simulation.base][INFO   ]

        Plasma stratification: (base.py:631)
Shell No. t_rad next_t_rad w next_w
0 1.11e+04 K 1.11e+04 K 0.464 0.466
5 1.13e+04 K 1.13e+04 K 0.177 0.177
10 1.1e+04 K 1.11e+04 K 0.113 0.111
15 1.07e+04 K 1.07e+04 K 0.0848 0.0853
[tardis.simulation.base][INFO   ]

        Current t_inner = 10641.692 K
        Expected t_inner for next iteration = 10650.463 K
 (base.py:658)
[tardis.simulation.base][INFO   ]

        Simulation finished in 19 iterations
        Simulation took 57.60 s
 (base.py:548)
[tardis.simulation.base][INFO   ]

        Starting iteration 20 of 20 (base.py:450)
[tardis.simulation.base][INFO   ]

        Luminosity emitted   = 1.061e+43 erg / s
        Luminosity absorbed  = 3.401e+42 erg / s
        Luminosity requested = 1.059e+43 erg / s
 (base.py:663)

Note

The virtual packet logging capability must be active in order to produce the Last Interaction Velocity Plot for virtual packets population. Thus, make sure to set virtual_packet_logging: True in your configuration file if you want to generate the Last Interaction Velocity Plot with virtual packets. It should be added under the virtual property of the spectrum property, as described in the configuration schema.

Now, import the plotting interface for Last Interaction Velocity Plot, i.e. the LIVPlotter class.

[2]:
from tardis.visualization.tools.liv_plot import LIVPlotter

And create a plotter object to process the data of simulation object sim for generating the Last Interaction Velocity plot.

[3]:
plotter = LIVPlotter.from_simulation(sim)

Static Plot (in matplotlib)

You can now call the generate_plot_mpl() method on your plotter object to create a highly informative and visually appealing Last Interaction Velocity plot using matplotlib.

Virtual packets mode

By default, a Last Interaction Velocity plot is produced for the virtual packet population of the simulation.

[4]:
plotter.generate_plot_mpl()
[4]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_10_1.svg

Real packets mode

You can produce a Last Interaction Velocity plot for the real packet population of the simulation by setting packets_mode="real" which is "virtual" by default.

[5]:
plotter.generate_plot_mpl(packets_mode="real")
[5]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_12_1.svg

Plotting a specific wavelength range

You can also restrict the wavelength range of escaped packets that you want to plot by specifying packet_wvl_range. It should be a quantity in Angstroms, containing two values - lower lambda and upper lambda i.e. [lower_lambda, upper_lambda] * u.AA.

[6]:
from astropy import units as u
[7]:
plotter.generate_plot_mpl(packet_wvl_range=[3000, 9000] * u.AA)
[tardis.visualization.tools.liv_plot][INFO   ]
        ['O III', 'Si IV', 'S IV', 'Ar I', 'Ar IV'] were not found in the provided wavelength range. (liv_plot.py:239)
[7]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_15_2.svg

Plotting only the top contributing elements

The nelements option allows you to plot the top contributing elements to the spectrum. Only the top elements are shown in the plot. Please note this works only for elements and not for ions.

[8]:
plotter.generate_plot_mpl(nelements=3)
[8]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_18_1.svg

Choosing what elements/ions to plot

You can pass a species_list for the species you want plotted in the Last Interaction Velocity Plot. Valid options include elements (e.g., Si), ions (specified in Roman numeral format, e.g., Si II), a range of ions (e.g., Si I-III), or any combination of these.

[9]:
plotter.generate_plot_mpl(species_list = ["Si I-III", "O", "Ca", "S"])
[9]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_20_1.svg

When using both the nelements and the species_list options, species_list takes precedence.

[10]:
plotter.generate_plot_mpl(species_list = ["Si I-III", "Ca", "S"], nelements=3)
[tardis.visualization.tools.liv_plot][INFO   ]
        Both nelements and species_list were requested. Species_list takes priority; nelements is ignored (liv_plot.py:420)
[10]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_22_2.svg

Plotting a specific number of bins

You can regroup the bins with broader widths within the same velocity range using num_bins.

[11]:
plotter.generate_plot_mpl(species_list = ["Si I-III", "O", "Ca", "S"], num_bins=10)
[11]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_24_1.svg

Plotting on the Log Scale

You can plot on the log scale on x-axis using xlog_scale=True and on y-axis using ylog_scale=True by default both are set to False which plots on a linear scale.

[12]:
plotter.generate_plot_mpl(species_list = ["Si I-III", "O", "Ca", "S"], xlog_scale=True, ylog_scale=True)
[12]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_26_1.svg

Plotting a specific velocity range

You can restrict the range of bins to plot in the Last Interaction Velocity Plot by specifying a valid velocity_range.

[13]:
plotter.generate_plot_mpl(species_list = ["Si I-III", "O", "Ca", "S"], velocity_range=(12500, 15050))
[13]:
<Axes: xlabel='Last Interaction Velocity (km/s)', ylabel='Packet Count'>
../../_images/io_visualization_how_to_liv_plot_28_1.svg

Additional plotting options

[14]:
# To list all available options (or parameters) with their description
help(plotter.generate_plot_mpl)
Help on method generate_plot_mpl in module tardis.visualization.tools.liv_plot:

generate_plot_mpl(species_list=None, nelements=None, packets_mode='virtual', packet_wvl_range=None, ax=None, figsize=(11, 5), cmapname='jet', xlog_scale=False, ylog_scale=False, num_bins=None, velocity_range=None) method of tardis.visualization.tools.liv_plot.LIVPlotter instance
    Generate the last interaction velocity distribution plot using matplotlib.

    Parameters
    ----------
    species_list : list of str, optional
        List of species to plot. Default is None which plots all species in the model.
    nelements : int, optional
        Number of elements to include in plot. The most interacting elements are included. If None, displays all elements.
    packets_mode : str, optional
        Packet mode, either 'virtual' or 'real'. Default is 'virtual'.
    packet_wvl_range : astropy.Quantity
        Wavelength range to restrict the analysis of escaped packets. It
        should be a quantity having units of Angstrom, containing two
        values - lower lambda and upper lambda i.e.
        [lower_lambda, upper_lambda] * u.AA
    ax : matplotlib.axes.Axes, optional
        Axes object to plot on. If None, creates a new figure.
    figsize : tuple, optional
        Size of the figure. Default is (11, 5).
    cmapname : str, optional
        Colormap name. Default is 'jet'. A specific colormap can be chosen, such as "jet", "viridis", "plasma", etc.
    xlog_scale : bool, optional
        If True, x-axis is scaled logarithmically. Default is False.
    ylog_scale : bool, optional
        If True, y-axis is scaled logarithmically. Default is False.
    num_bins : int, optional
        Number of bins for regrouping within the same range. Default is None.
    velocity_range : tuple, optional
        Limits for the x-axis. If specified, overrides any automatically determined limits.

    Returns
    -------
    matplotlib.axes.Axes
        Axes object with the plot.

The generate_plot_mpl method also has options specific to the matplotlib API, thereby providing you with more control over how your last interaction velocity looks. Possible cases where you may use them are:

  • ax: To plot on an Axis of a plot you’re already working with, e.g. for subplots.

  • figsize: To resize the plot as per your requirements.

  • cmapname: To use a colormap of your preference, instead of “jet”.

Interactive Plot (in plotly)

If you’re using the Last Interaction Velocity plot for exploration, consider creating an interactive version with generate_plot_ply(). This allows you to zoom, pan, inspect data values by hovering, resize the scale, and more conveniently.

This method takes the same arguments as ``generate_plot_mpl`` except for a few specific to the Plotly library. You can produce all the plots shown above in Plotly by passing the same arguments.

Virtual packets mode

By default, a Last Interaction Velocity plot is produced for the virtual packet population of the simulation.

[15]:
plotter.generate_plot_ply()

Real packets mode

You can produce a Last Interaction Velocity plot for the real packet population of the simulation by setting packets_mode="real" which is "virtual" by default.

[16]:
plotter.generate_plot_ply(packets_mode="real")

Plotting a specific wavelength range

You can also restrict the wavelength range of escaped packets that you want to plot by specifying packet_wvl_range. It should be a quantity in Angstroms, containing two values - lower lambda and upper lambda i.e. [lower_lambda, upper_lambda] * u.AA.

[17]:
from astropy import units as u
[18]:
plotter.generate_plot_ply(packet_wvl_range=[3000, 9000] * u.AA)
[tardis.visualization.tools.liv_plot][INFO   ]
        ['O III', 'Si IV', 'S IV', 'Ar I', 'Ar IV'] were not found in the provided wavelength range. (liv_plot.py:239)

Plotting only the top contributing elements

The nelements option allows you to plot the top contributing elements to the spectrum. Only the top elements are shown in the plot. Please note this works only for elements and not for ions.

[19]:
plotter.generate_plot_ply(nelements=10)

Choosing what elements/ions to plot

You can pass a species_list for the species you want plotted in the Last Interaction Velocity Plot. Valid options include elements (e.g., Si), ions (specified in Roman numeral format, e.g., Si II), a range of ions (e.g., Si I-III), or any combination of these.

[20]:
plotter.generate_plot_ply(species_list = ["Si I-III", "Ca", "S"])

When using both the nelements and the species_list options, species_list takes precedence.

[21]:
plotter.generate_plot_ply(species_list = ["Si I-III", "Ca", "S"], nelements=3)
[tardis.visualization.tools.liv_plot][INFO   ]
        Both nelements and species_list were requested. Species_list takes priority; nelements is ignored (liv_plot.py:522)

Plotting a specific number of bins

You can regroup the bins with broader widths within the same velocity range using num_bins.

[22]:
plotter.generate_plot_ply(species_list = ["Si I-III", "Ca", "S"], num_bins=10)

Plotting on the Log Scale

You can plot on the log scale on x-axis using xlog_scale=True and on y-axis using ylog_scale=True by default both are set to False.

[23]:
plotter.generate_plot_ply(species_list = ["Si I-III", "Ca", "S"], xlog_scale=True, ylog_scale=True)

Plotting a specific velocity range

You can restrict the range of bins to plot in the Last Interaction Velocity Plot by specifying a valid velocity_range.

[24]:
plotter.generate_plot_ply(species_list = ["Si I-III", "Ca", "S"], velocity_range=(12500, 15050))

Additional plotting options

[25]:
# To list all available options (or parameters) with their description
help(plotter.generate_plot_ply)
Help on method generate_plot_ply in module tardis.visualization.tools.liv_plot:

generate_plot_ply(species_list=None, nelements=None, packets_mode='virtual', packet_wvl_range=None, fig=None, graph_height=600, cmapname='jet', xlog_scale=False, ylog_scale=False, num_bins=None, velocity_range=None) method of tardis.visualization.tools.liv_plot.LIVPlotter instance
    Generate the last interaction velocity distribution plot using plotly.

    Parameters
    ----------
    species_list : list of str, optional
        List of species to plot. Default is None which plots all species in the model.
    nelements : int, optional
        Number of elements to include in plot. The most interacting elements are included. If None, displays all elements.
    packets_mode : str, optional
        Packet mode, either 'virtual' or 'real'. Default is 'virtual'.
    packet_wvl_range : astropy.Quantity
        Wavelength range to restrict the analysis of escaped packets. It
        should be a quantity having units of Angstrom, containing two
        values - lower lambda and upper lambda i.e.
        [lower_lambda, upper_lambda] * u.AA
    fig : plotly.graph_objects.Figure, optional
        Plotly figure object to add the plot to. If None, creates a new figure.
    graph_height : int, optional
        Height (in px) of the plotly graph to display. Default value is 600.
    cmapname : str, optional
        Colormap name. Default is 'jet'. A specific colormap can be chosen, such as "jet", "viridis", "plasma", etc.
    xlog_scale : bool, optional
        If True, x-axis is scaled logarithmically. Default is False.
    ylog_scale : bool, optional
        If True, y-axis is scaled logarithmically. Default is False.
    num_bins : int, optional
        Number of bins for regrouping within the same range. Default is None.
    velocity_range : tuple, optional
        Limits for the x-axis. If specified, overrides any automatically determined limits.

    Returns
    -------
    plotly.graph_objects.Figure
        Plotly figure object with the plot.

The generate_plot_ply method also has options specific to the plotly API, thereby providing you with more control over how your last interaction velocity plot looks. Possible cases where you may use them are:

  • fig: To plot the last interaction velocity plot on a figure you are already using e.g. for subplots.

  • graph_height: To specify the height of the graph as needed.

  • cmapname: To use a colormap of your preference instead of “jet”.

Using simulation saved as HDF

Other than producing the Last Interaction Velocity Plot for simulation objects in runtime, you can also produce it for saved TARDIS simulations.

[26]:
# hdf_plotter = LIVPlotter.from_hdf("demo.h5") ## Files is too large - just as an example

This hdf_plotter object is similar to the plotter object we used above, so you can use each plotting method demonstrated above with this too.

[27]:
# Static plot with virtual packets mode
# hdf_plotter.generate_plot_mpl()
[28]:
# Static plot with real packets mode
#hdf_plotter.generate_plot_mpl(packets_mode="real")
[29]:
# Interactive plot with virtual packets mode and specific list of species
# hdf_plotter.generate_plot_ply(species_list=["Si I-III", "Ca", "O", "S"])
[30]:
# Interactive plot with virtual packets mode and regrouped bins
# hdf_plotter.generate_plot_ply(num_bins=10)