Skip to content

Commit

Permalink
Merge pull request #47 from sunpy/gallery_v3_stuart_hates_this_one_trick
Browse files Browse the repository at this point in the history
gallery plus api docs
  • Loading branch information
Cadair authored May 8, 2024
2 parents 3aeb1b7 + 89f29c3 commit c94f0b1
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 21 deletions.
1 change: 1 addition & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.. automodapi:: mpl_animators
27 changes: 23 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config

import datetime
from pathlib import Path

# -- Project information -----------------------------------------------------

project = 'mpl-animators'
copyright = '2021, The SunPy Developers'
author = 'The SunPy Developers'
project = "mpl-animators"
author = "The SunPy Community"
copyright = f"{datetime.datetime.now(datetime.timezone.utc).year}, {author}" # NOQA: A001
author = "The SunPy Developers"

# The full version, including alpha/beta/rc tags
from mpl_animators import __version__
Expand All @@ -34,6 +37,7 @@
'sphinx.ext.mathjax',
'sphinx_automodapi.automodapi',
'sphinx_automodapi.smart_resolver',
"sphinx_gallery.gen_gallery",
]

# Add any paths that contain templates here, relative to this directory.
Expand Down Expand Up @@ -77,8 +81,23 @@
# -- Options for HTML output -------------------------------------------------

from sunpy_sphinx_theme.conf import * # NOQA

from sunpy_sphinx_theme import PNG_ICON
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']

# -- Sphinx Gallery ------------------------------------------------------------
sphinx_gallery_conf = {
"backreferences_dir": (Path("generated") / "modules").absolute(),
"filename_pattern": "^((?!skip_).)*$",
"examples_dirs": (Path("..") / "examples").absolute(),
"gallery_dirs": (Path("generated") / "gallery").absolute(),
"matplotlib_animations": True,
"default_thumb_file": PNG_ICON, # NOQA
"abort_on_example_error": False,
"plot_gallery": "True",
"remove_config_comments": True,
"doc_module": ("mpl_animators"),
"only_warn_on_example_error": True,
}
14 changes: 7 additions & 7 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
Matplotlib Animators Documentation
----------------------------------
***************************
mpl-animators Documentation
***************************

The ``mpl_animators`` package provides a set of classes which allow the easy construction of interactive `matplotlib` widget based animations.
"Out of the box" classes are provided for making line or image plots from numpy arrays, with sliders to control the animation automatically added for all dimensions not on the axes of the plot.
As well as this there is a specialised `.ArrayAnimatorWCS` class which can make line or image plots for a numpy array and associated World Coordinate System (WCS) object from `astropy`.
Finally, there are two base classes: `.BaseFuncAnimator` which can be extended to generate an interactive visualization from any data structure and set of functions to update the plot, and `.ArrayAnimator` which can be extended to generate any visualisation based on the axes of a numpy array.


.. automodapi:: mpl_animators

.. toctree::
:maxdepth: 2
:caption: Contents:
:hidden:

generated/gallery/index
api
6 changes: 6 additions & 0 deletions examples/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
***************
Example Gallery
***************

The gallery contains examples of how to use mpl-animators.
Each example is a short and self contained how-to guide for performing a specific task.
87 changes: 87 additions & 0 deletions examples/arrayanimatorwcs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
==============================================
Creating a visualization with ArrayAnimatorWCS
==============================================
This example shows how to create a simple visualization using
`~mpl_animators.ArrayAnimatorWCS`.
"""
import astropy.units as u
import astropy.wcs
import matplotlib.pyplot as plt
import sunpy.map
from astropy.visualization import AsinhStretch, ImageNormalize
from sunpy.data.sample import AIA_171_IMAGE, AIA_193_IMAGE
from sunpy.time import parse_time

from mpl_animators import ArrayAnimatorWCS

################################################################################
# To showcase how to visualize a sequence of 2D images using
# `~mpl_animators.ArrayAnimatorWCS`, we will use images from
# our sample data. The problem with this is that they are not part of
# a continuous dataset. To overcome this we will do two things.
# Create a stacked array of the images and create a `~astropy.wcs.WCS` header.
# The easiest method for the array is to create a `~sunpy.map.MapSequence`.

# Here we only use two files but you could pass in a larger selection of files.
map_sequence = sunpy.map.Map(AIA_171_IMAGE, AIA_193_IMAGE, sequence=True)

# Now we can just cast the sequence away into a NumPy array.
sequence_array = map_sequence.as_array()

# We'll also define a common normalization to use in the animations
norm = ImageNormalize(vmin=0, vmax=3e4, stretch=AsinhStretch(0.01))

###############################################################################
# Now we need to create the `~astropy.wcs.WCS` header that
# `~mpl_animators.ArrayAnimatorWCS` will need.
# To create the new header we can use the stored meta information from the
# ``map_sequence``.

# Now we need to get the time difference between the two observations.
t0, t1 = map(parse_time, [k["date-obs"] for k in map_sequence.all_meta()])
time_diff = (t1 - t0).to(u.s)

m = map_sequence[0]

wcs = astropy.wcs.WCS(naxis=3)
wcs.wcs.crpix = u.Quantity([0 * u.pix, *list(m.reference_pixel)])
wcs.wcs.cdelt = [time_diff.value, *list(u.Quantity(m.scale).value)]
wcs.wcs.crval = [0, m._reference_longitude.value, m._reference_latitude.value]
wcs.wcs.ctype = ["TIME", *list(m.coordinate_system)]
wcs.wcs.cunit = ["s", *list(m.spatial_units)]
wcs.wcs.aux.rsun_ref = m.rsun_meters.to_value(u.m)

# Now the resulting WCS object will look like:
print(wcs)

###############################################################################
# Now we can create the animation.
# `~mpl_animators.ArrayAnimatorWCS` requires you to select which
# axes you want to plot on the image. All other axes should have a ``0`` and
# sliders will be created to control the value for this axis.

wcs_anim = ArrayAnimatorWCS(sequence_array, wcs, [0, "x", "y"], norm=norm).get_animation()

plt.show()

###############################################################################
# You might notice that the animation could do with having the axes look
# neater. `~mpl_animators.ArrayAnimatorWCS` provides a way of setting
# some display properties of the `~astropy.visualization.wcsaxes.WCSAxes`
# object on every frame of the animation via use of the ``coord_params`` dict.
# They keys of the ``coord_params`` dict are either the first half of the
# ``CTYPE`` key, the whole ``CTYPE`` key or the entries in
# ``wcs.world_axis_physical_types`` here we use the short ctype identifiers for
# the latitude and longitude axes.

coord_params = {
"hpln": {"axislabel": "Helioprojective Longitude", "ticks": {"spacing": 10 * u.arcmin, "color": "black"}},
"hplt": {"axislabel": "Helioprojective Latitude", "ticks": {"spacing": 10 * u.arcmin, "color": "black"}},
}

# We have to recreate the visualization since we displayed it earlier.
wcs_anim = ArrayAnimatorWCS(sequence_array, wcs, [0, "x", "y"], norm=norm, coord_params=coord_params).get_animation()

plt.show()
52 changes: 52 additions & 0 deletions examples/lineanimator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
===========================
How to use the LineAnimator
===========================
This example shows off some ways in which you can use the
LineAnimator object to animate line plots.
"""
import matplotlib.pyplot as plt
import numpy as np

from mpl_animators import LineAnimator

###############################################################################
# Animate a 2D cube of random data as a line plot along an
# axis where the x-axis drifts with time.

# Define some random data
data_shape0 = (10, 20)
rng = np.random.default_rng()
data0 = rng.random(data_shape0)

###############################################################################
# Define the axis that will make up the line plot.

plot_axis0 = 1
slider_axis0 = 0

###############################################################################
# Let's customize the values along the x-axis. To do this, we must define the
# edges of the pixels/bins being plotted along the x-axis. This requires us to
# supply an array, say xdata, of length equal to data.shape[plot_axis_index]+1.
# In this example, the data has a shape of (10, 20) and let's say we are
# iterating through the 0th axis and plotting the 1st axis,
# i.e. plot_axis_index=1. Therefore we need to define an xdata array of length
# 21.
# This will give the same customized x-axis values for each frame of the
# animation. However, what if we want the x-axis values to change as we
# animate through the other dimensions of the cube? To do this we supply a
# (10, 21) xdata where each row (i.e. xdata[i, :]) gives the pixel/bin edges
# along the x-axis for the of the i-th frame of the animation. Note that this
# API extends in the same way to higher dimension. In our 2D case here though,
# we can define our non-constant x-axis values like so:

xdata = np.tile(np.linspace(0, 100, (data_shape0[plot_axis0] + 1)), (data_shape0[slider_axis0], 1))

###############################################################################
# Generate animation object with variable x-axis data.

ani = LineAnimator(data0, plot_axis_index=plot_axis0, axis_ranges=[None, xdata]).get_animation()

plt.show()
2 changes: 2 additions & 0 deletions mpl_animators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
from mpl_animators.wcs import *

from .version import __version__

__all__ = ["ArrayAnimator", "BaseFuncAnimator", "LineAnimator", "ArrayAnimatorWCS", "ImageAnimator", "__version__"]
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"mpl_animators.tests.test_basefuncanimator.test_lineanimator_figure": "6865a446680cb7088d71becd653e3c9e9e8e982d71956c95f690d52365bfe106",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_simple_plot": "1d0b9c13e72d288e09d1ab85fe3b4df38d6b349eae661c54cf32c18f0af451c6",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_clip_interval": "a78d4ca84423abcde116efeef4631cdf36d98033c71ad038363a033857743776",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_simple_plot": "7cf4b83a10ff179afd40d142860edfac340b922f42647eeae5ae9426627a6c63",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_clip_interval": "f03cf2632d825991cdfa5c5a15542fc53dc3a90d29cb21dabe858365f3f8c4b1",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_celestial_sliders": "14fc82e6778a7725092a691f210f05420e5669099fe8cb21260fd44336e57f8e",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_update_plot": "0c4a39742b55c4c9eb1336de59891c1e1459e656992505528f245783e4c7cf12",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_transpose_update_plot": "fca79fbb72e9650df3e64beb383b68a7816cfdfd95fa632386f65b5e6d32b5e4",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_colorbar_buttons": "dc5d08188e888fb6b93843b38a1604b8847aec38dc1ba53fa8ef108da6e790d6",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_colorbar_buttons_default_labels": "3026f941a8cf87347e6793b6002dda370eae6036e13961ae7323c3a4fe60d1d1",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_extra_sliders": "fd94e25c0b6a813818c8ab1b42c6d8828e546acf30ea9bc73164e50b22f456ba",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_update_plot": "6d328b74049bb415245901d033efdc103b55b11156a94e483da3c54615057c4b",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_transpose_update_plot": "eca32f981221be9268155d12c3662891951516ea1166a9a17c239eedb4b28c92",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_colorbar_buttons": "1ac74e4adb0fca87e99dee372842302130a90b8c5d2547b4ed9e14a60c9b8e96",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_colorbar_buttons_default_labels": "7dd4f77842219e790df3297773e581382164b00f0dc72c40379f5fca33ed4c36",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_2d_extra_sliders": "67fb82ca58a293bbcebcc06432a919c1aed54fb671a0be0e9d9289645d7897c0",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_1d_update_plot": "0618fba2b4285904d3594b4b3d76ebd56337cf2ad4c00aa568ac111f6d3e52aa",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_1d_update_plot_masked": "ae635463aaa2da4d494e9e90f040d39adf452eda92ad5f1c988b5be0bf437185",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_coord_params": "6535c5d4c7cfb9699bf99c4ad1919e9854626c5633eaa4d9aa97d5003408634a",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_coord_params": "ba389aca68e8cba9fcaf2e966cc909fba7b7f3e4ba4d65ad3035dae9c8056d57",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_coord_params_no_ticks": "536034d8e761ef5d2fdfbf8911c4ab9bbc96308328594befb44d0837eccd671e",
"mpl_animators.tests.test_wcs.test_array_animator_wcs_coord_params_grid": "5b81acf2215c9b8c1a700e2e7371f43be3177363abfe9729b6746eedd7d16686"
"mpl_animators.tests.test_wcs.test_array_animator_wcs_coord_params_grid": "6dacd902ec7ac3e9b34dac8554ef2a83a5b3a12ad5ddf63858511ac6fe02d417"
}
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ tests =
docs =
sphinx
sphinx-automodapi
sphinx-gallery
sunpy-sphinx-theme
sunpy[all]

[tool:pytest]
testpaths = "mpl_animators" "docs"
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ changedir = .tmp/{envname}
description =
run tests
figure: with figure tests
oldestdeps: and with oldest supported dependancies
oldestdeps: and with oldest supported dependencies
devdeps: and with development versions of matplotlib and astropy
deps =
pytest-xdist
Expand Down

0 comments on commit c94f0b1

Please sign in to comment.