Skip to content

Commit

Permalink
gallery plus api
Browse files Browse the repository at this point in the history
  • Loading branch information
nabobalis committed May 7, 2024
1 parent 3aeb1b7 commit 8437b66
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 13 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
25 changes: 22 additions & 3 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 @@ -82,3 +86,18 @@
# 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,
}
3 changes: 3 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ Finally, there are two base classes: `.BaseFuncAnimator` which can be extended t
.. toctree::
:maxdepth: 2
:caption: Contents:

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"
}
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tests =
docs =
sphinx
sphinx-automodapi
sphinx-gallery
sunpy-sphinx-theme

[tool:pytest]
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 8437b66

Please sign in to comment.