Creating Multi-panel plots with hermpy#

This example demonstrates how to construct multi-panel time series plots using hermpy.plotting.MultiPanel. We fetch one hour of MESSENGER MAG and FIPS data, parse them into their respective data structures, and progressively build up a combined plot.

import xarray as xr
from astropy.table import QTable
from sunpy.time import TimeRange

from hermpy.data import fips_energy_bin_edges, parse_messenger_fips, parse_messenger_mag
from hermpy.net import ClientMESSENGER
from hermpy.plotting import MultiPanel, SpectrogramPanel, TimeseriesPanel

First we must get some data. Here we fetch MESSENGER MAG and FIPS data for a particular time range.

We use hermpy.net.ClientMESSENGER to download MAG and FIPS data for a one-hour window. See here for more details.

c = ClientMESSENGER()
time_range = TimeRange("2011-09-26T12:00", "2011-09-26T13:20")

c.query(time_range, "MAG")
mag_file_paths = c.fetch()

c.query(time_range, "FIPS")
fips_file_paths = c.fetch()
Files Downloaded:   0%|          | 0/1 [00:00<?, ?file/s]

MAGMSOSCI11269_V08.TAB:   0%|          | 0.00/73.1M [00:00<?, ?B/s]

MAGMSOSCI11269_V08.TAB:   0%|          | 1.02k/73.1M [00:00<2:48:51, 7.21kB/s]

MAGMSOSCI11269_V08.TAB:   0%|          | 98.9k/73.1M [00:00<02:51, 427kB/s]

MAGMSOSCI11269_V08.TAB:   1%|          | 540k/73.1M [00:00<00:38, 1.88MB/s]

MAGMSOSCI11269_V08.TAB:   3%|▎         | 2.34M/73.1M [00:00<00:09, 7.43MB/s]



1/0 files failed to download. Please check `.errors` for details

Files Downloaded:   0%|          | 0/1 [00:00<?, ?file/s]
Files Downloaded:   0%|          | 0/1 [00:00<?, ?file/s]
Failed to download all files. Retrying (1/3).

Files Downloaded:   0%|          | 0/1 [00:00<?, ?file/s]

MAGMSOSCI11269_V08.TAB:   0%|          | 0.00/73.1M [00:00<?, ?B/s]

MAGMSOSCI11269_V08.TAB:   0%|          | 1.02k/73.1M [00:00<3:04:07, 6.61kB/s]

MAGMSOSCI11269_V08.TAB:   0%|          | 98.9k/73.1M [00:00<02:57, 412kB/s]

MAGMSOSCI11269_V08.TAB:   1%|          | 443k/73.1M [00:00<00:52, 1.38MB/s]

MAGMSOSCI11269_V08.TAB:   3%|▎         | 1.84M/73.1M [00:00<00:14, 4.95MB/s]

MAGMSOSCI11269_V08.TAB:   9%|▉         | 6.41M/73.1M [00:00<00:03, 17.0MB/s]

MAGMSOSCI11269_V08.TAB:  16%|█▌        | 11.5M/73.1M [00:00<00:02, 27.0MB/s]

MAGMSOSCI11269_V08.TAB:  25%|██▌       | 18.4M/73.1M [00:00<00:01, 39.5MB/s]

MAGMSOSCI11269_V08.TAB:  31%|███       | 22.7M/73.1M [00:00<00:01, 36.8MB/s]

MAGMSOSCI11269_V08.TAB:  36%|███▋      | 26.6M/73.1M [00:01<00:01, 36.9MB/s]

MAGMSOSCI11269_V08.TAB:  43%|████▎     | 31.6M/73.1M [00:01<00:01, 40.6MB/s]

MAGMSOSCI11269_V08.TAB:  49%|████▉     | 35.9M/73.1M [00:01<00:01, 35.5MB/s]

MAGMSOSCI11269_V08.TAB:  54%|█████▍    | 39.8M/73.1M [00:01<00:00, 36.4MB/s]

MAGMSOSCI11269_V08.TAB:  62%|██████▏   | 45.1M/73.1M [00:01<00:00, 41.0MB/s]

MAGMSOSCI11269_V08.TAB:  68%|██████▊   | 49.4M/73.1M [00:01<00:00, 41.3MB/s]

MAGMSOSCI11269_V08.TAB:  75%|███████▍  | 54.7M/73.1M [00:01<00:00, 44.7MB/s]

MAGMSOSCI11269_V08.TAB:  81%|████████  | 59.2M/73.1M [00:01<00:00, 43.9MB/s]

MAGMSOSCI11269_V08.TAB:  88%|████████▊ | 64.4M/73.1M [00:01<00:00, 44.6MB/s]

MAGMSOSCI11269_V08.TAB:  95%|█████████▌| 69.5M/73.1M [00:02<00:00, 46.1MB/s]


Files Downloaded: 100%|██████████| 1/1 [00:02<00:00,  2.41s/file]
Files Downloaded: 100%|██████████| 1/1 [00:02<00:00,  2.41s/file]

Files Downloaded:   0%|          | 0/1 [00:00<?, ?file/s]

FIPS_R2011269CDR_V3.TAB:   0%|          | 0.00/12.2M [00:00<?, ?B/s]

FIPS_R2011269CDR_V3.TAB:   0%|          | 1.02k/12.2M [00:00<39:30, 5.14kB/s]

FIPS_R2011269CDR_V3.TAB:   1%|          | 98.9k/12.2M [00:00<00:33, 364kB/s]

FIPS_R2011269CDR_V3.TAB:   7%|▋         | 834k/12.2M [00:00<00:04, 2.51MB/s]

FIPS_R2011269CDR_V3.TAB:  28%|██▊       | 3.47M/12.2M [00:00<00:00, 8.98MB/s]

FIPS_R2011269CDR_V3.TAB:  59%|█████▉    | 7.24M/12.2M [00:00<00:00, 15.5MB/s]

FIPS_R2011269CDR_V3.TAB:  92%|█████████▏| 11.2M/12.2M [00:00<00:00, 19.8MB/s]


Files Downloaded: 100%|██████████| 1/1 [00:01<00:00,  1.28s/file]
Files Downloaded: 100%|██████████| 1/1 [00:01<00:00,  1.28s/file]

We use Astropy’s Quantity Table (QTable) for time series data, and Xarray’s Dataset for 2D data. These custom parsers are included in hermpy.data, but may be replaced in later versions.

mag_data: QTable = parse_messenger_mag(mag_file_paths, time_range)
fips_data: xr.Dataset = parse_messenger_fips(fips_file_paths, time_range)
print(mag_data)
         UTC            X MSO     Y MSO     Z MSO      Bx      By      Bz
                          km        km        km       nT      nT      nT
--------------------- --------- --------- --------- ------- ------- --------
2011:269:12:00:00.020  -694.014   270.261  2615.208  231.18  -90.02 -393.552
2011:269:12:00:00.070  -694.192   270.249  2615.151 231.216  -90.01 -393.497
2011:269:12:00:00.120   -694.37   270.236  2615.094 231.344 -89.997 -393.423
2011:269:12:00:00.170  -694.548   270.224  2615.037 231.299 -89.997 -393.432
2011:269:12:00:00.220  -694.725   270.212   2614.98  231.38 -90.031 -393.358
2011:269:12:00:00.270  -694.903     270.2  2614.923 231.436 -90.084 -393.386
2011:269:12:00:00.320  -695.081   270.187  2614.865 231.435 -90.129 -393.378
2011:269:12:00:00.370  -695.259   270.175  2614.808 231.462 -90.063 -393.285
2011:269:12:00:00.420  -695.436   270.163  2614.751 231.507 -90.061 -393.276
                  ...       ...       ...       ...     ...     ...      ...
2011:269:13:19:59.520 -4028.764 -1001.012 -7865.931  17.683 -31.612    9.403
2011:269:13:19:59.570  -4028.74  -1001.02  -7866.01  18.151 -31.894    9.629
2011:269:13:19:59.620 -4028.717 -1001.028 -7866.089  18.667 -32.477    9.526
2011:269:13:19:59.670 -4028.693 -1001.036 -7866.168  19.133 -32.269    9.143
2011:269:13:19:59.720 -4028.669 -1001.044 -7866.247  18.947 -32.292    9.187
2011:269:13:19:59.770 -4028.646 -1001.052 -7866.326   18.48 -32.564    9.589
2011:269:13:19:59.820 -4028.622  -1001.06 -7866.405  17.875 -33.005    9.518
2011:269:13:19:59.870 -4028.599 -1001.068 -7866.484  17.596 -33.129    9.453
2011:269:13:19:59.920 -4028.575 -1001.076 -7866.563  17.919 -32.636   10.211
2011:269:13:19:59.970 -4028.551 -1001.084 -7866.642  17.822 -32.221   10.819
Length = 95995 rows
print(fips_data)
<xarray.Dataset> Size: 541kB
Dimensions:          (UTC: 505, Energy Channel: 63, Mode: 3407)
Coordinates:
  * UTC              (UTC) datetime64[us] 4kB 2011-09-26T12:00:02.262000 ... ...
  * Energy Channel   (Energy Channel) int64 504B 0 1 2 3 4 5 ... 58 59 60 61 62
  * Mode             (Mode) int64 27kB 2 2 2 2 2 2 2 2 2 2 ... 2 2 2 2 2 2 2 2 2
Data variables:
    Proton Flux      (UTC, Energy Channel) float64 255kB 0.0 0.0 0.0 ... 0.0 0.0
    Non-Proton Flux  (UTC, Energy Channel) float64 255kB 0.0 0.0 0.0 ... 0.0 0.0

As MESSENGER MAG data contains both ephemeris and magnetic field data, adding this data as it is to a Panel object will result in an error, as the columns (excluding the time column) have multiple units, and hence can’t be represented on the same axis.

We therefore need to shorten this table to just the columns we want in this Panel object.

mag_data.keep_columns(["UTC", "Bx", "By", "Bz"])

hermpy provides the Panel abstract base class, which is expanded upon in TimeseriesPanel and SpectrogramPanel.

We use a TimeseriesPanel as this matches the data type.

Each panel has a built-in plot function which returns a Figure and Axes for that panel in isolation. plt.show() is called within this function however uou can defer rendering until later by setting .plot(show=False), and then using plt.show() at a later point.

mag_panel = TimeseriesPanel(mag_data)
fig, ax = mag_panel.plot()
multipanel plots

Plotting with more than one panel#

The power in Panel objects comes when we go to construct multipanel plots. We can combine Panel objects to construct a multi-panel plot by simply adding them.

Lets make a second panel where we plot the FIPS data. We can combine the two using the addition operator. SpectrogramPanel doesn’t know anything about our data, so we need to provide the time axis, y axis, and y bin edges.

proton_flux = fips_data["Proton Flux"]
fips_panel = SpectrogramPanel(
    proton_flux,
    time_dim="UTC",
    y_dim="Energy Channel",
    y_bin_edges=fips_energy_bin_edges(),
    cmap="magma",
    unit="DEF [e / cm$^2$ s sr keV]",
)

We can set anything about the plot with ax_set_params

fips_panel.ax_set_params = {"ylabel": "E/q [keV/e]"}

multipanel: MultiPanel = mag_panel + fips_panel
fig, axes = multipanel.plot()
multipanel plots

You can also add multipanels to the same effect, and panels can also be added to multipanel objects.

multipanel += multipanel
multipanel.plot()
multipanel plots
(<Figure size 800x1000 with 4 Axes>, array([<Axes: ylabel='nT'>, <Axes: ylabel='E/q [keV/e]'>,
       <Axes: ylabel='nT'>, <Axes: ylabel='E/q [keV/e]'>], dtype=object))
multipanel += mag_panel
multipanel.plot()
multipanel plots
(<Figure size 800x1250 with 5 Axes>, array([<Axes: ylabel='nT'>, <Axes: ylabel='E/q [keV/e]'>,
       <Axes: ylabel='nT'>, <Axes: ylabel='E/q [keV/e]'>,
       <Axes: ylabel='nT'>], dtype=object))

Total running time of the script: (0 minutes 33.102 seconds)

Gallery generated by Sphinx-Gallery