Visualizing data with matplotlib¶
The module visualize_matplotlib
contains functions to easily
visualize Einstein Toolkit data with matplotlib
(Reference on kuibit.visualize_matplotlib).
Note
Visualizations are a subjective matter: different people have different
tastes, and it is impossible to have one-size-fits-all solutions.
visualize_matplotlib
comes with convenient functions to quickly
visualize data, but the module has default values that are opinionated. Where
possible, customization has been exposed for your convenience. However, some
settings and choices cannot be changed.
Series¶
Time and frequency series in kuibit
can be plotted with matplotlib
native functions. For example,
# Assuming rho_b is a TimeSeries
import matplotlib.pyplot as plt
plt.plot(rho_b)
Grid functions¶
The main way to visualize grid data is with the functions plot_color
and plot_contourf
. The first plots directly the values of the given
data, the second plots contours (filled). The functions support a large variety
of inputs:
NumPy arrays, with coordintes specified by the
coordinates
keyword.UniformGridData
: it will be plotted over the entire domain, unless the keywordsx0
,x1
andshape
are provided. These specify the extent of the grid to be plotted.shape
is essentially the resolution of the plot. See documentation on grid data for details.HierarchicalGridData
: it will be plotted over the entire domain, with resolution provided byshape
. The keywordsx0
,x1
can change the grid extent.BaseOneGridFunction
: same asHierarchicalGridData
, but you also have to provide the iteration with theiteration
keyword.
A table at the end of this document sums up these options. shape
, x0
,
x1
are all 2D lists or tuples.
The functions take additional arguments (for example, the labels for the axes). Details can be found in the reference material (Reference on kuibit.visualize_matplotlib).
Warning
Mask information will be lost upon resampling. If you want masks, you need to
provide the UniformGridData
you want to plot.
Plots can be enanched by adding a colorbar with plot_colorbar
(or
passing the colorbar
option).
The function plot_contour()
plots the contours without filling. It
requires the number of levels, or an array that specify where the levels are.
With plot_components_boundaries()
, you can plot the grid structure.
The function takes a HierarchicalGridData
as argument as plots its
grid structure. By defaults, ghost zones are not included, but they can be
passing remove_ghosts=False
. The function plots the boundaries of the single
components, but when multiple components can be merged into a single refinement
level, then only the outer boundary is plotted (a notable case in which this is
currently not possible is when there are multiple refinement centers).
Horizons¶
Apparent horizons can be plotted with plot_horizon()
. This
function takes the 2D shape of an horizon as returned by
shape_outline_at_iteration()
or shape_outline_at_time()
.
There are two wrappers around this function to simplify plotting horizons on the
usual planes xy
, xz
, and yz
:
plot_horizon_on_plane_at_iteration()
and
plot_horizon_on_plane_at_time()
. These take an
OneHorizon
object, the iteration/time that has to be plotted, and
the plane over which you are plotting. All these functions take also the color
of the horizon, the color of its boundary, and the opacity (alpha
).
Warning
When you take a cross section (an outline) of an horizon, kuibit
finds
points that are within a threshold to the plane that cuts the surface.
However, the way points are distributed on apparent horizons is highly
non-uniform. So, if you are cutting the horizon along an axis that is not one
of the coordinate ones (for the horizon), it is likely that too few points
will be close enough to the intersecting plane, resulting in a malformed or
absent outline. In some distant future, kuibit
will perform
interpolations to solve this problem.
Other utilities¶
setup_matplotlib¶
The default settings in matplotlib
are not great (e.g., the text is
typically too small). The function setup_matplotlib()
sets some
better defaults. Since “better” is relative, the function takes an optional
argument params
. This has to be dictionary with keys the parameters in
matplotlib
and values their new values. This can be used to override some of
the defaults in setup_matplotlib()
.
Note
The function setup_matplotlib()
simply updates the settings in
matplotlib
. It does not have any other effect.
add_text_to_corner¶
The function add_text_to_corner()
annotates a figure adding a label.
The location of the label can be specified with the node
argument. This is
identified with cardinal point (N,S,W, or E) or a combination of two of them.
For example, the default behavior is to place the text in the bottom right
corner (corresponding to South-East–SE). The distance from the border can also
be customized by passing the offset
argument.
save¶
The save()
function saves the figure to file. The function takes the
path of the output and saves the current figure. If the file has extension
.tikz
, then tikzplotlib
instead of matplotlib
is used to save the
figure. This results in a PGFPlots/TikZ ASCII file ready to be compiled with
LaTeX.
preprocess_plot and preprocess_plot_grid¶
preprocess_plot()
and preprocess_plot_grid()
are two
decorators. The first one adds support for passing figure
and axis
to a
function. Let us see how it works:
from kuibit.visualize_matplotlib import preprocess_plot
@preprocess_plot
def my_plot(data, figure=None, axis=None):
# My plotting, for example
ax.plot(data)
What preprocess_plot()
is the following: if the user provides
figure
and/or axis
, then those are used. If the user does not provide
those arguments, then the current one are used. This is roughly equivalent to
checking if figure is None
and if it is, then set figure = plt.gcf()
.
The second decorator is preprocess_plot_grid()
. With this, you can
forget about all the classes defined in kuibit
and simply plot NumPy arrays.
In more details: when you work with kuibit
, you will typically work with
HierarchicalGridData
and UniformGridData
. These are
complex structures that cannot be plotted immediately. The decorator
preprocess_plot_grid()
takes care of all the boilerplate needed to
work with those two classes so that the user can provide a
OneGridFunction
, UniformGridData
, a
HierarchicalGridData
, or a NumPy array. Let us see how it works:
from kuibit.visualize_matplotlib import preprocess_plot_grid
@preprocess_plot_grid
def my_plot(data, coordinates=None, figure=None, axis=None):
# My plotting, for example
ax.imshow(data)
# bob here is a H5OneGridFunction
# Some of the arguments are optional
my_plot(bob, shape=[500, 500], iteration=0, x0=[0, 0], x1=[1,1])
# rho_b here is a HierarchicalGridData
# Some of the arguments are optional
my_plot(rho_b, shape=[500, 500], x0=[0, 0], x1=[1,1])
# press here is a UniformGridData
# Some of the arguments are optional
my_plot(press, x0=[0,0])
# eps here is a NumPy array
my_plot(eps)
Depending on the type of object passed, additional arguments might be needed. See table below for details.
Type |
Arguments needed |
Arguments supported |
|
---|---|---|---|
|
|
||
|
|
||
|
|
||
2D NumPy array |
|