Animating PUNCH data#

How to animate PUNCH data using built-in plotting tools

First we’ll load a set of libraries. This is minimal, but will give us the tools to query a sample of data to download and animate. Note that for animation, you’ll need a local copy of ffmpeg, which can be installed through tools such as homebrew or conda. Depending on your environment you may also need to install a corresponding python package with a command such as pip install ffmpeg-python. Also note that punchbowl is in active development at the moment. To install the bleeding-edge version, use a command such as pip install git+https://github.com/punch-mission/punchbowl@main.

from sunpy.net import Fido
from sunpy.net import attrs as a

import punchbowl  # Note that this import is needed to register PUNCH fido tools
from punchbowl.data.visualize import animate_punch

Next we’ll query a sample of data to animate. Note that you can modify the time range, the product code, and the data version code. Two useful datasets to visualize are CAM and PAM - level 3 clear and polarized low-noise mosaics.

result = Fido.search(a.Time('2025/10/14 14:30:00', '2025/10/14 17:00:00'),
                     a.punch.ProductCode.ca, # (ca for clear low-noise), or pa for polarized low-noise, etc.
                     a.Instrument.m, # (m for mosaic), or a.Instrument.nfi_4, etc for earlier levels.
                     a.Level.three,
                     a.punch.DataVersion.newest, # or a.punch.DataVersion.zero_j, etc.
                     a.punch.FileType.fits) # or a.punch.FileType.jp2

result
Results from 1 Provider:

5 Results from the PUNCHClient:
QueryResponse length=5
Start TimeEnd TimeLevelProductCodeInstrumentDataVersionSourceProviderFileType
TimeTimestr1str2str1str2str5str4str4
2025-10-14 14:40:00.0002025-10-14 14:40:00.9993CAM0jPUNCHSwRIfits
2025-10-14 15:12:00.0002025-10-14 15:12:00.9993CAM0jPUNCHSwRIfits
2025-10-14 15:44:00.0002025-10-14 15:44:00.9993CAM0jPUNCHSwRIfits
2025-10-14 16:16:00.0002025-10-14 16:16:00.9993CAM0jPUNCHSwRIfits
2025-10-14 16:48:00.0002025-10-14 16:48:00.9993CAM0jPUNCHSwRIfits



The resulting files can then be downloaded. Note that occasionally data access through these tools can be down for maintenance or other issues. To instead query a list of local files you may have on hand, import the glob package into python, and then use a command such as files = glob.glob("path/to/files/*.fits") followed by files.sort().

files = Fido.fetch(result)
Files Downloaded:   0%|          | 0/5 [00:00<?, ?file/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:   0%|          | 0.00/22.7M [00:00<?, ?B/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:   0%|          | 0.00/22.7M [00:00<?, ?B/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:   0%|          | 0.00/22.7M [00:00<?, ?B/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:   0%|          | 0.00/22.7M [00:00<?, ?B/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:   0%|          | 0.00/22.7M [00:00<?, ?B/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:   1%|          | 232k/22.7M [00:00<00:09, 2.31MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:   2%|▏         | 345k/22.7M [00:00<00:06, 3.45MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:   1%|          | 278k/22.7M [00:00<00:08, 2.78MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:   1%|          | 265k/22.7M [00:00<00:08, 2.52MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:   1%|          | 185k/22.7M [00:00<00:13, 1.72MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  10%|█         | 2.28M/22.7M [00:00<00:01, 12.9MB/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:  11%|█         | 2.50M/22.7M [00:00<00:01, 13.9MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  11%|█         | 2.43M/22.7M [00:00<00:01, 13.2MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:   7%|▋         | 1.51M/22.7M [00:00<00:02, 8.27MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:  11%|█         | 2.45M/22.7M [00:00<00:01, 13.1MB/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:  22%|██▏       | 4.93M/22.7M [00:00<00:00, 18.4MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  20%|██        | 4.65M/22.7M [00:00<00:01, 17.1MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  18%|█▊        | 4.07M/22.7M [00:00<00:01, 14.6MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:  23%|██▎       | 5.30M/22.7M [00:00<00:00, 19.2MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  13%|█▎        | 2.94M/22.7M [00:00<00:01, 10.4MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  28%|██▊       | 6.44M/22.7M [00:00<00:00, 17.4MB/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:  33%|███▎      | 7.58M/22.7M [00:00<00:00, 20.5MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  27%|██▋       | 6.21M/22.7M [00:00<00:00, 16.8MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  20%|█▉        | 4.50M/22.7M [00:00<00:01, 12.4MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:  35%|███▍      | 7.92M/22.7M [00:00<00:00, 20.5MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  40%|████      | 9.14M/22.7M [00:00<00:00, 20.0MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  36%|███▌      | 8.18M/22.7M [00:00<00:00, 17.4MB/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:  43%|████▎     | 9.82M/22.7M [00:00<00:00, 20.3MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  26%|██▋       | 6.00M/22.7M [00:00<00:01, 12.9MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:  45%|████▌     | 10.2M/22.7M [00:00<00:00, 20.3MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  49%|████▉     | 11.2M/22.7M [00:00<00:00, 19.0MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  50%|█████     | 11.3M/22.7M [00:00<00:00, 20.9MB/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:  54%|█████▍    | 12.3M/22.7M [00:00<00:00, 20.7MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  37%|███▋      | 8.39M/22.7M [00:00<00:00, 15.7MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:  54%|█████▍    | 12.3M/22.7M [00:00<00:00, 19.3MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  61%|██████    | 13.8M/22.7M [00:00<00:00, 21.7MB/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:  64%|██████▍   | 14.6M/22.7M [00:00<00:00, 21.4MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  46%|████▌     | 10.4M/22.7M [00:00<00:00, 16.9MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  59%|█████▉    | 13.5M/22.7M [00:00<00:00, 19.5MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:  71%|███████   | 16.1M/22.7M [00:00<00:00, 25.0MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  54%|█████▍    | 12.3M/22.7M [00:00<00:00, 17.6MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  74%|███████▍  | 16.8M/22.7M [00:00<00:00, 23.3MB/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:  75%|███████▍  | 16.9M/22.7M [00:00<00:00, 21.4MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  70%|███████   | 16.0M/22.7M [00:00<00:00, 18.6MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:  82%|████████▏ | 18.7M/22.7M [00:00<00:00, 22.6MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  64%|██████▍   | 14.5M/22.7M [00:00<00:00, 18.8MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  87%|████████▋ | 19.8M/22.7M [00:00<00:00, 25.2MB/s]




PUNCH_L3_CAM_20251014161600_v0j.fits:  84%|████████▍ | 19.1M/22.7M [00:00<00:00, 19.5MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  79%|███████▉  | 17.9M/22.7M [00:01<00:00, 18.0MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  77%|███████▋  | 17.6M/22.7M [00:01<00:00, 22.4MB/s]



PUNCH_L3_CAM_20251014154400_v0j.fits:  91%|█████████ | 20.6M/22.7M [00:01<00:00, 20.4MB/s]





PUNCH_L3_CAM_20251014164800_v0j.fits:  89%|████████▉ | 20.3M/22.7M [00:01<00:00, 23.8MB/s]

PUNCH_L3_CAM_20251014144000_v0j.fits:  98%|█████████▊| 22.3M/22.7M [00:01<00:00, 19.4MB/s]


Files Downloaded:  20%|██        | 1/5 [00:01<00:05,  1.30s/file]










PUNCH_L3_CAM_20251014161600_v0j.fits:  93%|█████████▎| 21.0M/22.7M [00:01<00:00, 14.5MB/s]


PUNCH_L3_CAM_20251014151200_v0j.fits:  92%|█████████▏| 21.0M/22.7M [00:01<00:00, 13.8MB/s]




Files Downloaded:  60%|██████    | 3/5 [00:01<00:00,  2.31file/s]




PUNCH_L3_CAM_20251014161600_v0j.fits: 100%|█████████▉| 22.7M/22.7M [00:01<00:00, 10.5MB/s]








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

That file list is then passed into the animator function, along with an output filename.

animate_punch(files, output_path="PUNCH_CAM.mp4", axes_off=True, trim_edge=(0.13, 0.68))
  0%|          | 0/5 [00:00<?, ?it/s]
 20%|██        | 1/5 [00:04<00:16,  4.09s/it]
 40%|████      | 2/5 [00:04<00:05,  1.82s/it]
 60%|██████    | 3/5 [00:07<00:04,  2.29s/it]
 80%|████████  | 4/5 [00:07<00:01,  1.49s/it]
100%|██████████| 5/5 [00:10<00:00,  1.91s/it]
100%|██████████| 5/5 [00:10<00:00,  2.02s/it]

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

Gallery generated by Sphinx-Gallery