arpys.utilities package


arpys.utilities.constants module

A database like file containing numerical values of various natural constants in SI units. Alphabetically ordered by name (not by variable name).


Convert between electronvolt and nanometers for electromagnetic waves. The conversion follows from E = h*c/lambda and is simply:

nm_or_eV = 1239.84193 / eV_or_nm


eV_or_nm float; value in electronvolts or nanometers to be converted.


nm_or_eV float; if eV were given, this is the corresponding value in nanometers, or vice versa.

arpys.utilities.functions module

A module that provides custom functions.


Return a multidimensional array with increasing integer entries.


dims tuple of int; the lengths along each dimension.

Exploratory introspection function that outputs information on allattributes of an object. Tends to print a lot of output, so it might be advised to pipe or send it to a file over which one can easily search.


Return a polynomial function of order n.


n positive integer; the degree of the returned polynomial function.


p callable; a function that takes an independent variable x as its first argument and n more arguments representing the coefficients of the n’th order polynomial in increasing order.
arpys.utilities.functions.multiple_exponential(t, i=0, *A_TAU)[source]

Recursively build a function of the form:

f(t) = a1 * exp(-t/tau1) + a2 * exp(-t/tau2) + ... + an * exp(-t/taun)

and return its value at t. A_TAU must have length 2n, where n is the number of exponentials you want in the sum. t can be any argument that could be passed to the np.exp function.

The reason some of this seems weirdly implemented is because this function has been made compatible with scipy.optimize.curve_fit which unpacks parameters before passing them on to the fit function. Even now, some care has to be taken when passing arguments to this function directly - they probably have to be unpacked with the * operator, e.g.:

>>> multiple_exponential(np.array([1,2,3]), 0, *[0.5, 1, 0.5, 1])


t array_like; input (x-values) to the resulting function.
i int; iteration level
A_TAU list of length 2n; the first n entries are amplitude parameters for the different terms and the last n entries are the decay times of each term
arpys.utilities.functions.stretched_exponential(t, A, tau, h)[source]

Implement stretched exponentail decay:

f(t) = A * exp( - (t/tau)^(1/h) )
arpys.utilities.functions.lorentzian(x, a0, xmax, gamma)[source]
\[a_0 \cdot \frac{\Gamma^2}{(x-x_\mathrm{max})^2 + \Gamma^2}\]


x float or array; the variable.
a0 float; normalization factor.
xmax float; peak position of the Lorentzian in x units.
gamma float; peak width in x units.
arpys.utilities.functions.chi2(y, f, sigma, normalize=True)[source]

Return the chi-square value for a series of measured values y and uncertainties sigma that are described by model f:

                y_i - f_i
chi2 = sum_i( (-----------)^2 )

Can be normalized by the number of entries.


y np.array; values of the data which is to be described
f np.array; values predicted by the model
sigma np.array or float; uncertainties on values y
normalize boolean; whether to divide the result by the length of y or not
arpys.utilities.functions.indexof(value, array)[source]

Return the first index of the value in the array closest to the given value.


>>> a = np.array([1, 0, 0, 2, 1])
>>> indexof(0, a)
>>> indexof(0.9, a)

Sort the given lists by the elements in the first list.


>>> l0 = [3, 1, 2]
>>> l1 = ['b', 'c', 'a']
>>> l2 = [11, 22, 33]
>>> sort_together(l0, l1, l2)
[[1, 2, 3], ['c', 'a', 'b'], [22, 33, 11]]
>>> sort_together(l1, l0, l2)
[['a', 'b', 'c'], [2, 3, 1], [33, 11, 22]]

arpys.utilities.kolormap module

cdict = {'red':     ((),
         'green':   ((),
         'blue':    ((),

FFFFFF  255,255,255
EBCCFF  235,204,255
D699FF  214,153,255
C266FF  194,102,255
AD33FF  173, 51,255
9900FF  153,  0,255
7A00CC  122,  0,204
5C0099   92,  0,153
3D0066   61,  0,102
1F0033   31,  0, 51
000000    0,  0,  0
333300   51, 51,  0
666600  102,102,  0
999900  153,153,  0
CCCC00  204,204,  0
FFFF00  255,255,  0
FFFF33  255,255, 51
FFFF66  255,255,102
FFFF99  255,255,153
FFFFCC  255,255,204

Convert a color in hex notation (e.g. FFFFFF) to a normalized RGB tuple (in this example (1., 1., 1.)).

arpys.utilities.plotting module

Useful propcycle elements for plotting. Usage:

from matplotlib import rc
rc("axes", prop_cycle=<insert your cycler here>)
arpys.utilities.plotting.make_cycler(color=['#7b5db3', '#40b959', '#bb543e', '#c8ab42', '#0c214b', '#7ce1d1', '#ad2e6e', '#161300'], **kwargs)[source]

Create a cycler from different elements. The kwargs need to be :class: cycler keyword arguments.

arpys.utilities.plotting.advance_cycler(ax, n=1)[source]

Advance the state of a cycler by n steps.


ax matplotlib.axes._suplots.AxesSubplot instance; The subplot in which to advance the cycler.
n int; The number of steps to advance the cycler by

Rewind the cycler to the last position that was used, i.e. the next line will have the same colour as the last one that was drawn. Note: this is done very crudely - if you know the length of your cycler it might be better to just use the ‘advance_cycler’ method with argument ‘len(cycler)-1’.


ax matplotlib.axes._suplots.AxesSubplot instance; The subplot in which to advance the cycler.
arpys.utilities.plotting.set_cycler(color=['#7b5db3', '#40b959', '#bb543e', '#c8ab42', '#0c214b', '#7ce1d1', '#ad2e6e', '#161300'], **kwargs)[source]

Shorthand for setting the cycler. Uses kustom.plotting.make_cycler to create a cycler according to given kwargs and imports and updates matplotlibrc.

arpys.utilities.plotting.make_n_colors(n=8, cmap='plasma')[source]

Pick n equidistant colors from the colormap specified with cmap. Returns a list of rgba color tuples.

class arpys.utilities.plotting.MidpointNorm(vmin=None, vmax=None, midpoint=None, clip=False)[source]

Bases: matplotlib.colors.Normalize

A norm that maps the values between vmin and midpoint to the range 0-0.5 and the values from midpoint to vmax to 0.5-1. This is ideal for a bivariate colormap where the data is split in two regions of interest of different extents.

class arpys.utilities.plotting.DynamicNorm(vmin=None, vmax=None, n=None, bins=None, clip=False)[source]

Bases: matplotlib.colors.Normalize

A norm which maps high density data regions to proportionally larger intervals in color space.

class arpys.utilities.plotting.cursorax(*args, **kwargs)[source]

Bases: matplotlib.axes._axes.Axes

name = 'cursor'
cursor_x = None
cursor_y = None
color = 'red'
lw = 1

Return the min and max for the x and y axes, depending on whether xscale and yscale are defined.


Depending on whether we have actual data scales (self.xscale and self.yscale are defined) or not, return arrays which represent data coordinates.


Return the cursor position.

class arpys.utilities.plotting.cursorpolyax(*args, **kwargs)[source]

Bases: arpys.utilities.plotting.cursorax

A cursorax that allows drawing of a draggable polygon-ROI.

By clicking on the plot, a cursor appears which behaves and can be accessed the same way as in cursorax. Additionally, hitting the draw_key (d by default) puts user in polygon-draw mode where each subsequent click on the plot adds another corner to a polygon until it is completed by clicking on the starting point again. Once finished, each click just moves the cursor, as before. Hitting the remove_key (e by default) removes the polygon from the plot. At the moment of the polygon’s completion, the function on_polygon_complete is executed. This function is a stub in the class definition and can be overwritten/reassigned by the user to perform any action desired on polygon completion. The vertices of the last completed polygon are present as an argument to on_polygon_complete and can also be accessed by vertices at any time.

The actual magic here is done by PolygonSelector which this class mostly just provides a simple interface for …

Known bugs:
  • Using PolygonSelector’s default ‘remove’ key (Esc) messes up reaction to cursorpolyax’ keybinds.
  • Shift-dragging polygon makes the cursor jump.
name = 'cursorpoly'
poly = None
vertices = None
polylineprops = {'color': 'r', 'lw': '1'}
polymarkerprops = {'marker': 'None'}
draw_key = 'd'
remove_key = 'e'
useblit = False

Handle keyboard press events. If the pressed key matches :attr: draw_key <cursorax.draw_key> or :attr: remove_key <cursorpolyax.remove_key> and the figure is not draw-locked, carry out the respective operations.


Ensure that the next click after this fcn call will start drawing the polygon.


Handle mouse-click events. Just call the superclass’ on_click method, which positions the cursor at the clicked location. That method check’s itself whether the draw lock is free, so we don’t get cursor jumps while we’re drawing a polygon.


Make the polygon invisible, remove the reference to it (which should cause the underlying :class: PolygonSelector <matplotlib.widgets.PolygonSelector> object to be garbage collected) and release the draw lock.


This method should be overridden/redefined by user.

Module contents

Collection of homebrew python modules.