Source code for eloy.viz

"""
Visualization utilities for astronomical images.

This module provides functions for image scaling and for plotting
marks and labels on matplotlib axes.
"""

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import patches
from astropy.visualization import ZScaleInterval


[docs] def z_scale(data, c=0.05): """ Compute z-scale interval for image display. Parameters ---------- data : np.ndarray 2D image data. c : float, optional Contrast parameter for ZScaleInterval. Returns ------- tuple (vmin, vmax) for display scaling. """ interval = ZScaleInterval(contrast=c) return interval(data.copy())
[docs] def plot_marks( x, y, label=None, position="bottom", offset=7, fontsize=12, color=[0.51, 0.86, 1.0], ms=12, n=None, inside=True, alpha=1, ax=None, ): """ Plot circular marks and optional labels on a matplotlib axis. Parameters ---------- x : array-like X coordinates. y : array-like Y coordinates. label : array-like or None, optional Labels for each mark. position : str, optional Position of the label ("top" or "bottom"). offset : float, optional Offset for label position. fontsize : int, optional Font size for labels. color : list or str, optional Color for marks and labels. ms : float, optional Marker size. n : int or None, optional Number of marks to plot. inside : bool, optional Only plot marks inside axis limits. alpha : float, optional Alpha transparency. ax : matplotlib.axes.Axes or None, optional Axis to plot on. Returns ------- None """ y_offset = ms + offset if position == "top": y_offset *= -1 if not isinstance(x, (list, np.ndarray, tuple)): x = np.array([x]) y = np.array([y]) if label is True: label = np.array([0]) elif label is not None: label = np.array([label]) else: if label is True: label = np.arange(len(x)) elif label is not None: label = np.array(label) if ax is None: ax = plt.gcf().axes[0] if inside: ax = ax xlim, ylim = np.array(ax.get_xlim()), np.array(ax.get_ylim()) xlim.sort() ylim.sort() within = np.argwhere( np.logical_and.reduce([xlim[0] < x, x < xlim[1], ylim[0] < y, y < ylim[1]]) ).flatten() x = x[within] y = y[within] if label is not None: print label = label[within] if n is not None: x = x[0:n] y = y[0:n] if label is not None: label = label[0:n] if label is None: label = [None for _ in range(len(x))] for _x, _y, _label in zip(x, y, label): circle = patches.Circle((_x, _y), ms, fill=None, ec=color, alpha=alpha) ax.add_artist(circle) f = 5 if _label is not None: plt.annotate( _label, xy=[_x, _y - y_offset], color=color, ha="center", fontsize=fontsize, alpha=alpha, va="top" if position == "bottom" else "bottom", )