Plot a map of velocities

This is an example showing how to produce a map showing the spatial distribution of velocities in a 2D region of the Sun.

First we shall create a random 2D grid of velocities that can be plotted. Usually you would use a method such as mcalf.models.FitResults.velocities() to extract an array of velocities from fitted spectra.

import numpy as np

x = 50  # 50 coordinates along x-axis
y = 40  # 40 coordinates along y-axis
low, high = -10, 10  # range of velocities (km/s)

def a(x, y, low, high):
    arr = np.random.normal(0, (high - low) / 2 * 0.3, (y, x))
    arr[arr < low] = low
    arr[arr > high] = high
    i = np.random.randint(0, arr.size, arr.size // 100)
    arr[np.unravel_index(i, arr.shape)] = np.nan
    return arr

arr = a(x, y, low, high)  # 2D array of velocities (y, x)

Next, we shall import mcalf.visualisation.plot_map().

from mcalf.visualisation import plot_map

We can now simply plot the 2D array.

plot plot map
<matplotlib.image.AxesImage object at 0x7f0cc79778e0>

Notice that pixels with missing data (NaN) are shown in grey.

By default, the velocity data are assumed to have units km/s. If your data are not in km/s, you must either 1) rescale the array such that it is in km/s, 2) attach an astropy unit to the array to override the default, or 3) pass an astropy unit to the unit parameter to override the default. For example, we can change from km/s to m/s,

import astropy.units as u

plot_map(arr * 1000 * u.m / u.s)
plot plot map
<matplotlib.image.AxesImage object at 0x7f0cc7ac0dc0>

A spatial resolution with units can be specified for each axis.

plot_map(arr, resolution=(0.5 *, 0.6 * u.Mm), offset=(-25, -20))
plot plot map
<matplotlib.image.AxesImage object at 0x7f0cc6cfc820>

A narrower range of velocities to be plotted can be requested with the vmin and vmax parameters. Classifications outside of the range will appear saturated. Providing only one of vmin and vmax with set the other such that zero is the midpoint.

plot_map(arr, vmax=4)
plot plot map
<matplotlib.image.AxesImage object at 0x7f0cc79f0e20>

A mask can be applied to the velocity array to isolate a region of interest. This functionally is useful if, for example, data only exist for a circular region and you want to distinguish between the pixels that are out of bounds and the data that were not successfully fitted.

from mcalf.utils.mask import genmask
mask = genmask(50, 40, 18)

plot_map(arr, ~mask)
plot plot map
<matplotlib.image.AxesImage object at 0x7f0cc69931c0>

Notice how data out of bounds are grey, while data which were not fitted successfully are now black.

A region of interest, typically the umbra of a sunspot, can be outlined by passing a different mask.

umbra_mask = genmask(50, 40, 5, 5, 5)

plot_map(arr, ~mask, umbra_mask)
plot plot map
<matplotlib.image.AxesImage object at 0x7f0cc5522bb0>

The plot_map function integrates well with matplotlib, allowing extensive flexibility.

import matplotlib.pyplot as plt

fig, ax = plt.subplots(1, 2, constrained_layout=True)

plot_map(arr[:, :25], vmax=6, ax=ax[0], show_colorbar=False)
im = plot_map(arr[:, 25:], vmax=6, ax=ax[1], show_colorbar=False)

fig.colorbar(im, ax=ax, location='bottom', label='velocity (km/s)')

ax[0].set_title('first half')
ax[1].set_title('second half')
first half, second half

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

Gallery generated by Sphinx-Gallery