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
np.random.seed(0)

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_map(arr)
plot plot map

Out:

<matplotlib.image.AxesImage object at 0x7ff801b92c10>

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

Out:

<matplotlib.image.AxesImage object at 0x7ff81a0bc610>

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

plot_map(arr, resolution=(0.5 * u.km, 0.6 * u.Mm), offset=(-25, -20))
plot plot map

Out:

<matplotlib.image.AxesImage object at 0x7ff8183aba00>

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

Out:

<matplotlib.image.AxesImage object at 0x7ff801ca4100>

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

Out:

<matplotlib.image.AxesImage object at 0x7ff818335a90>

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

Out:

<matplotlib.image.AxesImage object at 0x7ff801c47a30>

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')

plt.show()
first half, second half

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

Gallery generated by Sphinx-Gallery