pept.Voxels#

class pept.Voxels(voxels_array, xlim, ylim, zlim, **kwargs)[source]#

Bases: object

A class managing a 3D voxel space with physical dimensions, including tools for voxel manipulation and visualisation.

The .voxels attribute is simply a numpy.ndarray[ndim=3, dtype=float64]. The .attrs dictionary can be used to store extra information.

See also

konigcell.Pixels

A class managing a physical 2D pixel space.

konigcell.dynamic3d

Rasterize moving particles’ trajectories.

konigcell.static3d

Rasterize static particles’ positions.

konigcell.dynamic_prob3d

3D probability distribution of a quantity.

Attributes
voxels(M, N, P) np.ndarray[ndim=3, dtype=float64]

The 3D numpy array containing the voxel values. This class assumes a uniform grid of voxels - that is, the voxel size in each dimension is constant, but can vary from one dimension to another.

xlim(2,) np.ndarray[ndim=1, dtype=float64]

The lower and upper boundaries of the voxellised volume in the x-dimension, formatted as [x_min, x_max].

ylim(2,) np.ndarray[ndim=1, dtype=float64]

The lower and upper boundaries of the voxellised volume in the y-dimension, formatted as [y_min, y_max].

zlim(2,) np.ndarray[ndim=1, dtype=float64]

The lower and upper boundaries of the voxellised volume in the z-dimension, formatted as [z_min, z_max].

voxel_size(3,) np.ndarray[ndim=1, dtype=float64]

The lengths of a voxel in the x-, y- and z-dimensions, respectively.

voxel_grids(3,) list[np.ndarray[ndim=1, dtype=float64]]

A list containing the voxel gridlines in the x-, y-, and z-dimensions. Each dimension’s gridlines are stored as a numpy of the voxel delimitations, such that it has length (M + 1), where M is the number of voxels in given dimension.

lower(3,) np.ndarray[ndim=1, dtype=float64]

The lower left corner of the voxel box; corresponds to [xlim[0], ylim[0], zlim[0]].

upper(3,) np.ndarray[ndim=1, dtype=float64]

The upper right corner of the voxel box; corresponds to [xlim[1], ylim[1], zlim[1]].

attrsdict[Any, Any]

A dictionary storing any other user-defined information.

__init__(voxels_array, xlim, ylim, zlim, **kwargs)[source]#

Voxels class constructor.

Parameters
voxels_array3D numpy.ndarray

A 3D numpy array, corresponding to a pre-defined voxel space.

xlim(2,) numpy.ndarray

The lower and upper boundaries of the voxellised volume in the x-dimension, formatted as [x_min, x_max].

ylim(2,) numpy.ndarray

The lower and upper boundaries of the voxellised volume in the y-dimension, formatted as [y_min, y_max].

zlim(2,) numpy.ndarray

The lower and upper boundaries of the voxellised volume in the z-dimension, formatted as [z_min, z_max].

**kwargsextra keyword arguments

Extra user-defined attributes to be saved in .attrs.

Raises
ValueError

If voxels_array does not have exactly 3 dimensions or if xlim, ylim or zlim do not have exactly 2 values each.

Methods

__init__(voxels_array, xlim, ylim, zlim, ...)

Voxels class constructor.

add_lines(lines[, verbose])

Voxellise a sample of lines, adding 1 to each voxel traversed, for each line in the sample.

copy([voxels_array, xlim, ylim, zlim])

Create a copy of the current Voxels instance, optionally with new voxels_array, xlim and / or ylim.

cube_trace(index[, color, opacity, ...])

Get the Plotly Mesh3d trace for a single voxel at index.

cubes_traces([condition, color, opacity, ...])

Get a list of Plotly Mesh3d traces for all voxels selected by the condition filtering function.

from_lines(lines, number_of_voxels[, xlim, ...])

Create a voxel space and traverse / voxellise a given sample of lines.

from_physical(locations[, corner])

Transform locations from physical dimensions to voxel indices.

heatmap_trace([ix, iy, iz, width, ...])

Create and return a Plotly Heatmap trace of a 2D slice through the voxels.

load(filepath)

Load a saved / pickled Voxels object from filepath.

plot([condition, ax, alt_axes])

Plot the voxels in this class using Matplotlib.

plot_volumetric([condition, mode, colorscale])

Create a volumetric PyVista plot - check the mode argument for the available types.

save(filepath)

Save a Voxels instance as a binary pickle object.

scatter_trace([condition, size, color, ...])

Create and return a trace for all the voxels in this class, with possible filtering.

to_physical(indices[, corner])

Transform indices from voxel indices to physical dimensions.

vtk([condition])

Return a PyVista VTK object, exposing all VTK functionality.

zeros(shape, xlim, ylim, zlim, **kwargs)

Create a Voxels object filled with zeros.

Attributes

attrs

lower

upper

voxel_grids

voxel_size

voxels

xlim

ylim

zlim

property voxels#
property xlim#
property ylim#
property zlim#
property voxel_size#
property voxel_grids#
property lower#
property upper#
property attrs#
save(filepath)[source]#

Save a Voxels instance as a binary pickle object.

Saves the full object state, including the inner .voxels NumPy array, xlim, etc. in a fast, portable binary format. Load back the object using the load method.

Parameters
filepathfilename or file handle

If filepath is a path (rather than file handle), it is relative to where python is called.

Examples

Save a Voxels instance, then load it back:

>>> import numpy as np
>>> import konigcell as kc
>>>
>>> grid = np.zeros((64, 48, 32))
>>> voxels = kc.Voxels(grid, [0, 20], [0, 10])
>>> voxels.save("voxels.pickle")
>>> voxels_reloaded = kc.Voxels.load("voxels.pickle")
static load(filepath)[source]#

Load a saved / pickled Voxels object from filepath.

Most often the full object state was saved using the .save method.

Parameters
filepathfilename or file handle

If filepath is a path (rather than file handle), it is relative to where python is called.

Returns
pept.Voxels

The loaded pept.Voxels instance.

Examples

Save a Voxels instance, then load it back:

>>> import numpy as np
>>> import konigcell as kc
>>>
>>> grid = np.zeros((64, 48, 32))
>>> voxels = kc.Voxels(grid, [0, 20], [0, 10])
>>> voxels.save("voxels.pickle")
>>> voxels_reloaded = kc.Voxels.load("voxels.pickle")
copy(voxels_array=None, xlim=None, ylim=None, zlim=None, **kwargs)[source]#

Create a copy of the current Voxels instance, optionally with new voxels_array, xlim and / or ylim.

The extra attributes in .attrs are propagated too. Pass new attributes as extra keyword arguments.

static zeros(shape, xlim, ylim, zlim, **kwargs)[source]#

Create a Voxels object filled with zeros.

from_physical(locations, corner=False)[source]#

Transform locations from physical dimensions to voxel indices. If corner = True, return the index of the bottom left corner of each voxel; otherwise, use the voxel centres.

Examples

Create a simple konigcell.Voxels grid, spanning [-5, 5] mm in the X-dimension, [10, 20] mm in the Y-dimension and [0, 10] in Z:

>>> import konigcell as kc
>>> voxels = kc.Voxels.zeros((5, 5, 5), xlim=[-5, 5], ylim=[10, 20],
                             zlim=[0, 10])
>>> voxels
Voxels
------
xlim = [-5.  5.]
ylim = [10. 20.]
zlim = [10. 20.]
voxels =
  (shape: (5, 5, 5))
  [[[0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]
    ...
    [0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]]
   [[0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]
    ...
    [0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]]
   ...
   [[0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]
    ...
    [0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]]
   [[0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]
    ...
    [0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]]]
attrs = {}
>>> voxels.voxel_size
array([2., 2., 2.])

Transform physical coordinates to voxel coordinates:

>>> voxels.from_physical([-5, 10, 0], corner = True)
array([0., 0., 0.])
>>> voxels.from_physical([-5, 10, 0])
array([-0.5, -0.5, -0.5])

The voxel coordinates are returned exactly, as real numbers. For voxel indices, round them into values:

>>> voxels.from_physical([0, 15, 0]).astype(int)
array([2, 2, 0])

Multiple coordinates can be given as a 2D array / list of lists:

>>> voxels.from_physical([[0, 15, 0], [5, 20, 10]])
array([[ 2. ,  2. , -0.5],
       [ 4.5,  4.5,  4.5]])
to_physical(indices, corner=False)[source]#

Transform indices from voxel indices to physical dimensions. If corner = True, return the coordinates of the bottom left corner of each voxel; otherwise, use the voxel centres.

Examples

Create a simple konigcell.Voxels grid, spanning [-5, 5] mm in the X-dimension, [10, 20] mm in the Y-dimension and [0, 10] in Z:

>>> import konigcell as kc
>>> voxels = kc.Voxels.zeros((5, 5, 5), xlim=[-5, 5], ylim=[10, 20],
                             zlim=[0, 10])
>>> voxels
Voxels
------
xlim = [-5.  5.]
ylim = [10. 20.]
zlim = [10. 20.]
voxels =
  (shape: (5, 5, 5))
  [[[0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]
    ...
    [0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]]
   [[0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]
    ...
    [0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]]
   ...
   [[0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]
    ...
    [0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]]
   [[0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]
    ...
    [0. 0. ... 0. 0.]
    [0. 0. ... 0. 0.]]]
attrs = {}
>>> voxels.voxel_size
array([2., 2., 2.])

Transform physical coordinates to voxel coordinates:

>>> voxels.to_physical([0, 0, 0], corner = True)
array([-5., 10., 0.])
>>> voxels.to_physical([0, 0, 0])
array([-4., 11., 1.])

Multiple coordinates can be given as a 2D array / list of lists:

>>> voxels.to_physical([[0, 0, 0], [4, 4, 3]])
array([[-4., 11.,  1.],
       [ 4., 19.,  7.]])
plot(condition=<function Voxels.<lambda>>, ax=None, alt_axes=False)[source]#

Plot the voxels in this class using Matplotlib.

This plots the centres of all voxels encapsulated in a pept.Voxels instance, colour-coding the voxel value.

The condition parameter is a filtering function that should return a boolean mask (i.e. it is the result of a condition evaluation). For example lambda x: x > 0 selects all voxels that have a value larger than 0.

Parameters
conditionfunction, default lambda voxel_data: voxel_data > 0

The filtering function applied to the voxel data before plotting it. It should return a boolean mask (a numpy array of the same shape, filled with True and False), selecting all voxels that should be plotted. The default, lambda x: x > 0 selects all voxels which have a value larger than 0.

axmpl_toolkits.mplot3D.Axes3D object, optional

The 3D matplotlib-based axis for plotting. If undefined, new Matplotlib figure and axis objects are created.

alt_axesbool, default False

If True, plot using the alternative PEPT-style axes convention: z is horizontal, y points upwards. Because Matplotlib cannot swap axes, this is achieved by swapping the parameters in the plotting call (i.e. plt.plot(x, y, z) -> plt.plot(z, x, y)).

Returns
fig, ax

Matplotlib figure and axes objects.

Notes

Plotting all points is very computationally-expensive for matplotlib. It is recommended to only plot a couple of samples at a time, or use Plotly, which is faster.

Examples

Voxellise an array of lines and add them to a PlotlyGrapher instance:

>>> import konigcell as kc
>>>
>>> lines = np.array(...)           # shape (N, M >= 7)
>>> number_of_voxels = [10, 10, 10]
>>> voxels = kc.Voxels(lines, number_of_voxels)
>>> fig, ax = voxels.plot()
>>> fig.show()
plot_volumetric(condition=<function Voxels.<lambda>>, mode='box', colorscale='magma')[source]#

Create a volumetric PyVista plot - check the mode argument for the available types.

Parameters
conditionfunction, default lambda voxel_data: voxel_data > 0

The filtering function applied to the voxel data before plotting it. It should return a boolean mask (a numpy array of the same shape, filled with True and False), selecting all voxels that should be plotted. The default, lambda x: x > 0 selects all voxels which have a value larger than 0.

mode“box”, “plane”, “slice”

Use a VTK clip box, clip plane or clip slice.

colorscalestr, default “magma”

The PyVista colorscale to use.

Returns
pyvista.Plotter

A PyVista Figure object that can be .show().

vtk(condition=<function Voxels.<lambda>>)[source]#

Return a PyVista VTK object, exposing all VTK functionality.

Parameters
conditionfunction, default lambda voxel_data: voxel_data > 0

The filtering function applied to the voxel data before plotting it. It should return a boolean mask (a numpy array of the same shape, filled with True and False), selecting all voxels that should be plotted. The default, lambda x: x > 0 selects all voxels which have a value larger than 0.

Returns
pyvista.UniformGrid

A VTK UniformGrid object.

cube_trace(index, color=None, opacity=0.4, colorbar=True, colorscale='magma')[source]#

Get the Plotly Mesh3d trace for a single voxel at index.

This renders the voxel as a cube. While visually accurate, this method is very computationally intensive - only use it for fewer than 100 cubes. For more voxels, use the voxels_trace method.

Parameters
index(3,) tuple

The voxel indices, given as a 3-tuple.

colorstr or list-like, optional

Can be a single color (e.g. “black”, “rgb(122, 15, 241)”) or a colorbar list. Overrides colorbar if set. For more information, check the Plotly documentation. The default is None.

opacityfloat, default 0.4

The opacity of the lines, where 0 is transparent and 1 is fully opaque.

colorbarbool, default True

If set to True, will color-code the voxel values. Is overridden if color is set.

colorscalestr, default “Magma”

The Plotly scheme for color-coding the voxel values in the input data. Typical ones include “Cividis”, “Viridis” and “Magma”. A full list is given at plotly.com/python/builtin-colorscales/. Only has an effect if colorbar = True and color is not set.

Raises
ValueError

If index does not contain exactly three values.

Notes

If you want to render a small number of voxels as cubes using Plotly, use the cubes_traces method, which creates a list of individual cubes for all voxels, using this function.

cubes_traces(condition=<function Voxels.<lambda>>, color=None, opacity=0.4, colorbar=True, colorscale='magma')[source]#

Get a list of Plotly Mesh3d traces for all voxels selected by the condition filtering function.

The condition parameter is a filtering function that should return a boolean mask (i.e. it is the result of a condition evaluation). For example lambda x: x > 0 selects all voxels that have a value larger than 0.

This renders each voxel as individual cubes. While visually accurate, this method is very computationally intensive - only use it for fewer than 100 cubes. For more voxels, use the voxels_trace method.

Parameters
conditionfunction, default lambda voxels: voxels > 0

The filtering function applied to the voxel data before plotting it. It should return a boolean mask (a numpy array of the same shape, filled with True and False), selecting all voxels that should be plotted. The default, lambda x: x > 0 selects all voxels which have a value larger than 0.

colorstr or list-like, optional

Can be a single color (e.g. “black”, “rgb(122, 15, 241)”) or a colorbar list. Overrides colorbar if set. For more information, check the Plotly documentation. The default is None.

opacityfloat, default 0.4

The opacity of the lines, where 0 is transparent and 1 is fully opaque.

colorbarbool, default True

If set to True, will color-code the voxel values. Is overridden if color is set.

colorscalestr, default “magma”

The Plotly scheme for color-coding the voxel values in the input data. Typical ones include “Cividis”, “Viridis” and “Magma”. A full list is given at plotly.com/python/builtin-colorscales/. Only has an effect if colorbar = True and color is not set.

Examples

Plot a konigcell.Voxels on a plotly.graph_objs.Figure.

>>> import konigcell as kc
>>> voxels = ...
>>> import plotly.graph_objs as go
>>>
>>> fig = go.Figure()
>>> fig.add_traces(voxels.cubes_traces())  # small number of voxels
>>> fig.show()
scatter_trace(condition=<function Voxels.<lambda>>, size=4, color=None, opacity=0.4, colorbar=True, colorscale='Magma', colorbar_title=None)[source]#

Create and return a trace for all the voxels in this class, with possible filtering.

Creates a plotly.graph_objects.Scatter3d object for the centres of all voxels encapsulated in a pept.Voxels instance, colour-coding the voxel value.

The condition parameter is a filtering function that should return a boolean mask (i.e. it is the result of a condition evaluation). For example lambda x: x > 0 selects all voxels that have a value larger than 0.

Parameters
conditionfunction, default lambda voxel_data: voxel_data > 0

The filtering function applied to the voxel data before plotting it. It should return a boolean mask (a numpy array of the same shape, filled with True and False), selecting all voxels that should be plotted. The default, lambda x: x > 0 selects all voxels which have a value larger than 0.

sizefloat, default 4

The size of the plotted voxel points. Note that due to the large number of voxels in typical applications, the voxel centres are plotted as square points, which provides an easy to understand image that is also fast and responsive.

colorstr or list-like, optional

Can be a single color (e.g. “black”, “rgb(122, 15, 241)”) or a colorbar list. Overrides colorbar if set. For more information, check the Plotly documentation. The default is None.

opacityfloat, default 0.4

The opacity of the lines, where 0 is transparent and 1 is fully opaque.

colorbarbool, default True

If set to True, will color-code the voxel values. Is overridden if color is set.

colorscalestr, default “Magma”

The Plotly scheme for color-coding the voxel values in the input data. Typical ones include “Cividis”, “Viridis” and “Magma”. A full list is given at plotly.com/python/builtin-colorscales/. Only has an effect if colorbar = True and color is not set.

colorbar_titlestr, optional

If set, the colorbar will have this title above it.

Examples

Voxellise an array of lines and add them to a PlotlyGrapher instance:

>>> grapher = PlotlyGrapher()
>>> lines = np.array(...)           # shape (N, M >= 7)
>>> number_of_voxels = [10, 10, 10]
>>> voxels = pept.Voxels.from_lines(lines, number_of_voxels)
>>> grapher.add_lines(lines)
>>> grapher.add_trace(voxels.voxels_trace())
>>> grapher.show()
heatmap_trace(ix=None, iy=None, iz=None, width=0, colorscale='Magma', transpose=True)[source]#

Create and return a Plotly Heatmap trace of a 2D slice through the voxels.

The orientation of the slice is defined by the input ix (for the YZ plane), iy (XZ), iz (XY) parameters - which correspond to the voxel index in the x-, y-, and z-dimension. Importantly, at least one of them must be defined.

Parameters
ixint, optional

The index along the x-axis of the voxels at which a YZ slice is to be taken. One of ix, iy or iz must be defined.

iyint, optional

The index along the y-axis of the voxels at which a XZ slice is to be taken. One of ix, iy or iz must be defined.

izint, optional

The index along the z-axis of the voxels at which a XY slice is to be taken. One of ix, iy or iz must be defined.

widthint, default 0

The number of voxel layers around the given slice index to collapse (i.e. accumulate) onto the heatmap.

colorscalestr, default “Magma”

The Plotly scheme for color-coding the voxel values in the input data. Typical ones include “Cividis”, “Viridis” and “Magma”. A full list is given at plotly.com/python/builtin-colorscales/. Only has an effect if colorbar = True and color is not set.

transposebool, default True

Transpose the heatmap (i.e. flip it across its diagonal).

Raises
ValueError

If neither of ix, iy or iz was defined.

Examples

Voxellise an array of lines and add them to a PlotlyGrapher instance:

>>> lines = np.array(...)           # shape (N, M >= 7)
>>> number_of_voxels = [10, 10, 10]
>>> voxels = pept.Voxels(lines, number_of_voxels)
>>> import plotly.graph_objs as go
>>> fig = go.Figure()
>>> fig.add_trace(voxels.heatmap_trace())
>>> fig.show()
add_lines(lines, verbose=False)#

Voxellise a sample of lines, adding 1 to each voxel traversed, for each line in the sample.

Parameters
lines(M, N >= 7) numpy.ndarray

The sample of 3D lines to voxellise. Each line is defined as a timestamp followed by two 3D points, such that the data columns are [time, x1, y1, z1, x2, y2, z2, …]. Note that there can be extra data columns which will be ignored.

verbosebool, default False

Time the voxel traversal and print it to the terminal.

Raises
ValueError

If lines has fewer than 7 columns.

static from_lines(lines, number_of_voxels, xlim=None, ylim=None, zlim=None, verbose=True)#

Create a voxel space and traverse / voxellise a given sample of lines. The number_of_voxels in each dimension must be defined. If the voxel space boundaries xlim, ylim or zlim are not defined, they are inferred as the boundaries of the lines.

Parameters
lines(M, N>=7) numpy.ndarray or pept.LineData

The lines that will be voxellised, each defined by a timestamp and two 3D points, so that the data columns are [time, x1, y1, z1, x2, y2, z2, …]. Note that extra columns are ignored.

number_of_voxels(3,) list[int]

The number of voxels in the x-, y-, and z-dimensions, respectively.

xlim(2,) list[float], optional

The lower and upper boundaries of the voxellised volume in the x-dimension, formatted as [x_min, x_max]. If undefined, it is inferred from the boundaries of lines.

ylim(2,) list[float], optional

The lower and upper boundaries of the voxellised volume in the y-dimension, formatted as [y_min, y_max]. If undefined, it is inferred from the boundaries of lines.

zlim(2,) list[float], optional

The lower and upper boundaries of the voxellised volume in the z-dimension, formatted as [z_min, z_max]. If undefined, it is inferred from the boundaries of lines.

Returns
pept.Voxels

A new Voxels object with the voxels through which the lines were traversed.

Raises
ValueError

If the input lines does not have the shape (M, N>=7). If the number_of_voxels is not a 1D list with exactly 3 elements, or any dimension has fewer than 2 voxels.