Plotting a solar cycle index

This example demonstrates how to plot the solar cycle in terms of the number of sunspots and a prediction for the next few years.

import matplotlib.pyplot as plt

import astropy.units as u
from astropy.time import Time, TimeDelta

import sunpy.timeseries as ts
from sunpy.net import Fido
from sunpy.net import attrs as a
from sunpy.time import TimeRange

The U.S. Dept. of Commerce, NOAA, Space Weather Prediction Center (SWPC) provides recent solar cycle indices which includes different sunspot numbers, radio flux, and geomagnetic index. They also provide predictions for how the sunspot number and radio flux will evolve. Predicted values are based on the consensus of the Solar Cycle 24 Prediction Panel.

We will first search for and then download the data.

time_range = TimeRange("2008-06-01 00:00", Time.now())
result = Fido.search(a.Time(time_range), a.Instrument('noaa-indices'))
f_noaa_indices = Fido.fetch(result)
result = Fido.search(a.Time(time_range.end, time_range.end + TimeDelta(4 * u.year)),
                     a.Instrument('noaa-predict'))
f_noaa_predict = Fido.fetch(result)

Out:

Files Downloaded:   0%|          | 0/1 [00:00<?, ?file/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/locks.py:21: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._event = asyncio.Event(loop=loop)


observed-solar-cycle-indices.json: 0.00B [00:00, ?B/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(


observed-solar-cycle-indices.json: 100B [00:00, 740B/s]

observed-solar-cycle-indices.json: 100kB [00:00, 1.06kB/s]

observed-solar-cycle-indices.json: 315kB [00:00, 1.51kB/s]
Files Downloaded: 100%|##########| 1/1 [00:00<00:00,  1.67file/s]
Files Downloaded: 100%|##########| 1/1 [00:00<00:00,  1.67file/s]

Files Downloaded:   0%|          | 0/1 [00:00<?, ?file/s]/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/connector.py:964: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  hosts = await asyncio.shield(self._resolve_host(
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/aiohttp/locks.py:21: DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
  self._event = asyncio.Event(loop=loop)


predicted-solar-cycle.json: 0.00B [00:00, ?B/s]

predicted-solar-cycle.json: 13.1kB [00:00, 123kB/s]
Files Downloaded: 100%|##########| 1/1 [00:00<00:00,  4.52file/s]
Files Downloaded: 100%|##########| 1/1 [00:00<00:00,  4.51file/s]


                                                          

                                                   

We then load them into individual TimeSeries objects.

noaa = ts.TimeSeries(f_noaa_indices, source='noaaindices').truncate(time_range)
noaa_predict = ts.TimeSeries(f_noaa_predict, source='noaapredictindices')

Out:

/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/astropy/_erfa/core.py:104: ErfaWarning: ERFA function "dtf2d" yielded 2532 of "dubious year (Note 6)"
  warnings.warn('ERFA function "' + func_name + '" yielded ' + wmsg, ErfaWarning)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/astropy/_erfa/core.py:104: ErfaWarning: ERFA function "d2dtf" yielded 2532 of "dubious year (Note 5)"
  warnings.warn('ERFA function "' + func_name + '" yielded ' + wmsg, ErfaWarning)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/astropy/_erfa/core.py:104: ErfaWarning: ERFA function "dtf2d" yielded 1 of "dubious year (Note 6)"
  warnings.warn('ERFA function "' + func_name + '" yielded ' + wmsg, ErfaWarning)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/astropy/_erfa/core.py:104: ErfaWarning: ERFA function "dtf2d" yielded 192 of "dubious year (Note 6)"
  warnings.warn('ERFA function "' + func_name + '" yielded ' + wmsg, ErfaWarning)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/astropy/_erfa/core.py:104: ErfaWarning: ERFA function "d2dtf" yielded 192 of "dubious year (Note 5)"
  warnings.warn('ERFA function "' + func_name + '" yielded ' + wmsg, ErfaWarning)
/home/docs/checkouts/readthedocs.org/user_builds/sunpy/conda/stable/lib/python3.8/site-packages/astropy/_erfa/core.py:104: ErfaWarning: ERFA function "dtf2d" yielded 1 of "dubious year (Note 6)"
  warnings.warn('ERFA function "' + func_name + '" yielded ' + wmsg, ErfaWarning)

Finally, we plot both noaa and noaa_predict for the sunspot number. In this case we use the S.I.D.C. Brussels International Sunspot Number (RI). The predictions provide both a high and low values, which we plot below as ranges.

fig, ax = plt.subplots()
ax.plot(noaa.index, noaa.quantity('sunspot RI'), label='Sunspot Number')
ax.plot(noaa_predict.index, noaa_predict.quantity('sunspot'),
        color='grey', label='Near-term Prediction')
ax.fill_between(noaa_predict.index, noaa_predict.quantity('sunspot low'),
                noaa_predict.quantity('sunspot high'), alpha=0.3, color='grey')
ax.set_ylim(bottom=0)
ax.set_ylabel('Sunspot Number')
ax.set_xlabel('Year')
ax.legend()
plt.show()
solar cycle example

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

Gallery generated by Sphinx-Gallery