Source code for libertem.viz.bqp

import logging

import numpy as np

from .base import Live2DPlot


logger = logging.getLogger(__name__)


[docs]class BQLive2DPlot(Live2DPlot): """ bqplot-image-gl-based live plot. .. versionadded:: 0.7.0 Parameters ---------- dataset : DataSet The dataset on which the UDF will be run. This allows to determine the shape of the plots for initialization. udf : UDF The UDF instance this plot is associated to. This needs to be the same instance that is passed to :meth:`~libertem.api.Context.run_udf`. roi : numpy.ndarray or None Region of interest (ROI) that the UDF will be run on. This is necessary for UDFs where the `extra_shape` parameter of result buffers is a function of the ROI, such as :class:`~libertem.udf.raw.PickUDF`. channel : misc Indicate the channel to be plotted. - :code:`None`: The first plottable (2D) channel of the UDF is plotted. - :code:`str`: The UDF result buffer name that should be plotted. - :code:`tuple(str, function(ndarray) -> ndarray)`: The UDF result buffer name that should be plotted together with a function that extracts a plottable result - :code:`function(udf_result, damage) -> (ndarray, damage)`: Function that derives a plottable 2D ndarray and damage indicator from the full UDF results and the processed nav space. See :ref:`plotting` for more details! title : str The plot title. By default UDF class name and channel name. min_delta : float Minimum time span in seconds between updates to reduce overheads for slow plotting. udfresult : UDFResults, optional UDF result to initialize the plot data and determine plot shape. If None (default), this is determined using :meth:`~libertem.udf.base.UDFRunner.dry_run` on the dataset, UDF and ROI. This parameter allows re-using buffers to avoid unnecessary dry runs. """ def __init__( self, dataset, udf, roi=None, channel=None, title=None, min_delta=1/60, udfresult=None ): super().__init__( dataset=dataset, udf=udf, roi=roi, channel=channel, title=title, min_delta=min_delta, udfresult=udfresult, ) # keep bqplot and bqplot_image_gl as optional dependencies from bqplot import Figure, LinearScale, Axis, ColorScale from bqplot_image_gl import ImageGL scale_x = LinearScale(min=0, max=1) # Make sure y points down # See https://libertem.github.io/LiberTEM/concepts.html#coordinate-system scale_y = LinearScale(min=1, max=0) axis_x = Axis(scale=scale_x, label='x') axis_y = Axis(scale=scale_y, label='y', orientation='vertical') s = self.data.shape aspect = s[1] / s[0] figure = Figure( axes=[axis_x, axis_y], scale_x=scale_x, scale_y=scale_y, min_aspect_ratio=aspect, max_aspect_ratio=aspect, title=self.title ) color_scale = ColorScale(min=0, max=1) scales_image = {'x': scale_x, 'y': scale_y, 'image': color_scale} dtype = np.result_type(self.data, np.int8) image = ImageGL(image=self.data.astype(dtype), scales=scales_image) figure.marks = (image,) self.figure = figure self.image = image self.color_scale = color_scale
[docs] def display(self): from IPython.display import display display(self.figure)
[docs] def update(self, damage, force=False): dtype = np.result_type(self.data, np.int8) # Map on dtype that supports subtraction valid_data = self.data[damage].astype(dtype) valid_data = valid_data[np.isfinite(valid_data)] if valid_data.size > 0: mmin = valid_data.min() mmax = valid_data.max() else: mmin = 1 mmax = 1 + 1e-12 delta = mmax - mmin if delta <= 0: delta = 1 # Map on color scale range 0..1 self.image.image = (self.data.astype(dtype) - mmin) / delta