First, you will need to install it. First clone it from here:
https://gitlab.tudelft.nl/steelelab/data-explorer
You can install it by going to the location where you cloned it to and then run pip install:
pip install .
You will need some libraries. I have not yet figured out how to build this into the pip file. But you will need these:
numpy
xarray
matplotlib
bokeh
With those, you should be ready to go!
The data explorer module is named dexplore
and a quasi-convention is to import it as dx
:
It should trigger a loading of Bokeh. If your bokeh plots become unresponsive (I have had this with browser tabs connected to the jupyterhub), then you can reload the browser tab (not the kernel) and re-run the import to reload the Bokeh javasript into your browser.
This works for now only for files with meta.txt
files that specify the coordinate axis sizes, range and names.
If you do not have meta.txt
files, or if your data is in another format, you will need your own code to parse your data into xarrarys:
https://docs.xarray.dev/en/stable/
Here, we will load a random ASCII dat file from the NAS.
dat = "/home/jovyan/steelelab/measurement_data/Triton/Yildiz/"
dat += "data_analysis/data/Y1_2017_07_10_17.24.08_RF_vs_Vg_at0p015K_part2/"
dat += "Y1_2017_07_10_17.24.08_RF_vs_Vg_at0p015K_part2.dat"
data = dx.load_dat_meta_txt(dat)
This is what the resulting object looks like:
data
<xarray.Dataset> Dimensions: (Frequency (Hz): 2001, Voltage (V): 161, Nothing: 1) Coordinates: * Frequency (Hz) (Frequency (Hz)) float64 3e+07 3.014e+07 ... 3e+08 * Voltage (V) (Voltage (V)) float64 4.0 3.75 3.5 ... -35.75 -36.0 * Nothing (Nothing) float64 0.0 Data variables: Frequency (Hz) (column) (Frequency (Hz), Voltage (V), Nothing) float64 3... S21re () (Frequency (Hz), Voltage (V), Nothing) float64 -... S21im () (Frequency (Hz), Voltage (V), Nothing) float64 -... S21dB (dB) (Frequency (Hz), Voltage (V), Nothing) float64 -... S21Ph (rad) (Frequency (Hz), Voltage (V), Nothing) float64 -... Power (dBm) (Frequency (Hz), Voltage (V), Nothing) float64 -... Temperature (K) (Frequency (Hz), Voltage (V), Nothing) float64 0... Voltage (V) (column) (Frequency (Hz), Voltage (V), Nothing) float64 -... Attributes: datafile: /home/jovyan/steelelab/measurement_data/Triton/Yildiz/data_ana... metafile: /home/jovyan/steelelab/measurement_data/Triton/Yildiz/data_ana...
You can read more about what it can do in the help:
help(dx.load_dat_meta_txt)
Help on function load_dat_meta_txt in module dexplore.load_dat_meta_txt: load_dat_meta_txt(datfile, delimiter=',') Load .dat file with accomanying metadata in meta.txt format specification. Parameters ---------- datfile: Absolute path to a .dat file. delimiter: Specify the delimiter. Default is ",". Returns ------- data: xarray containing the data and metadata This routine expects that the dat file is accompanied by a file with same name but with .dat replaced with .meta.txt, specifying the coordinate and dataset names contained in the file according to the spyview specification: https://nsweb.tn.tudelft.nl/~gsteele/spyview/#meta Specifically, the meta.txt file format is defined by: # Lines that start with "#" are comments, and are ignored # # The first four lines contain the number of x points (ie. the inner loop, "sweep") # followed by the xmin, the xmax, and the xaxis label. 101 -500.0 400.0 Sweep gate (mV) # The next is the same for y (ie. secondmost inner loop, "loop1") 201 -10.0 10.0 Bias (mV) # The last is for z (outermost loop, "loop2") # If your dataset is only a 2D sweep, you can set these to "1", "0", "1" and "Nothing". 11 0 9 Magnetic Field (T) # Next, you can optionally add labels for each of the colums in the datset. # If you do not give a label, the data will be given a default # data name of "Column X" # For each column label, include one line with the column number, and a second # line giving the column data label 2 Current (pA) 5 Time per pixel (ms)
This will make a static, inline matplotlib plot. This is handy for saving / exporting as HTML, since the Bokeh plots do not export if you save the notebook as HTML_Embed (or at least, I haven't figured it out). I have configured it to plot the third column by default, since this is for us the most common.
It plot the first line along first axis by default. It will get the axis labels from the data array metadata.
dx.plot_line_cut(data)
You can see more about how to use it here:
help(dx.plot_line_cut)
Help on function plot_line_cut in module dexplore.static_plots: plot_line_cut(data, dataset=3, axis=0, pos=(0, 0, 0)) Plot a line cut from the supplied xarray Parameters ---------- data: A xarray which contains (max) 3 coordinates dataset: (default 1) Which dataset of the array to use for the plot. Can be either and integer corresponding to the index (column number for dat files) of the dataset, or it can be a string specifying the name of the dataset. axis: (default 0) An integer specifying along which coordinate axis the linecut should be taken. position: (default (0,0,0)) A tuple of integers specifying the index of the coordinates of the starting point of the linecut. The value of the axis corresonding to the linecut direction coordinate axis is ignored.
This will allow you to use controls in the notebook to change the index and axis of the linecut and change which dataset to plot. It will produce a bokeh plot, which means you can interactively pan / zoom through your data.
dx.interactive_linecut(data)
VBox(children=(HBox(children=(Dropdown(description='Linecut Along:', options=('Frequency (Hz)', 'Voltage (V)',…
This function will plot a static colormap of your data:
dx.plot_colormap(data)
It takes several optional parameters to change things, such as the colormap name and the gamma normalisation:
help(dx.plot_colormap)
Help on function plot_colormap in module dexplore.static_plots: plot_colormap(data, dataset=3, cut_axis=2, pos=0, cmap='RdBu_r', gamma=1) Plot a 2D colormap from the supplied xarray Parameters ---------- data: A xarray which contains (max) 3 coordinates dataset: (default 1) Which dataset of the array to use for the plot. Can be either and integer corresponding to the index (column number for dat files) of the dataset, or it can be a string specifying the name of the dataset. cut_axis: (default 2) An integer specifying from which coordinate axis the 2D colorplot should be sliced. position: (default 0) Index of plane to be sliced for the 2D colormap. cmap: (default "RdBu_r") The matplotlib colormap to be used. gamma: (default 1) The gamma that should be used for the normalisation. See matplotlib PowerNorm for more details.
This will create a bokeh interactive colormap with a slider for changing the gamma, a selector box for choosing the data variable to plot, a dropdown box for picking the colormap, and a slider for clicking through colormaps with the left and right keys.
Right now, the interactive version only supports colormaps of the data along the first two axes of your dataset, since that is what we need in the lab 99.99% of the time. In principle it could be extended to other slices of data with 3 coordinate axes (like plot_colormap()
above) but for now, I've kept the code simple.
dx.interactive_colormap(data)
VBox(children=(HBox(children=(FloatSlider(value=1.0, description='gamma:', max=5.0, min=0.05, step=0.01), Drop…
You can find out more about the options here:
help(dx.interactive_colormap)
Help on function interactive_colormap in module dexplore.interactive_colormap: interactive_colormap(data, initial_var=3, throttle_delay=0.2) Generate an interactive colormap from an xarray dataset Parameters ---------- data: A xarray dataset which contains (max) 3 coordinates initial_var: (default 3) Which dataset variable to start with when opening the widget. Either a number index of the dataset variable, or a dataset name. throttle_delay: (default 0.2) Throttle time in seconds. To prevent the UI interactions from falling behind, this function throttles calls to the bokeh updates. If your plots are taking a long time to finish updating after moving the slider, you can increase this time.
This is a function that generates a combined interactive colorplot and linecut. The position and direction of the linecut can be changed, and the position of the linecut is indicated by a line in the colormap.
For now, linecut position is controlled by a slider. At some point, I will look up how to get this from bokeh click events in the plot: should be easy, just haven't had time yet.
dx.interactive_linecut_and_colormap(data)
VBox(children=(HBox(children=(FloatSlider(value=1.0, description='gamma:', max=5.0, min=0.05, step=0.01), Drop…
help(dx.interactive_linecut_and_colormap)
Help on function interactive_linecut_and_colormap in module dexplore.interactive_linecut_and_colormap: interactive_linecut_and_colormap(data, initial_var=3, throttle_delay=0.2) Generate an interactive colormap from an xarray dataset Parameters ---------- data: A xarray dataset which contains (max) 3 coordinates initial_var: (default 3) Which dataset variable to start with when opening the widget. Either a number index of the dataset variable, or a dataset name. throttle_delay: (default 0.2) Throttle time in seconds. To prevent the UI interactions from falling behind, this function throttles calls to the bokeh updates. If your plots are taking a long time to finish updating after moving the slider, you can increase this time.
The idea of writing things like above as functions rather than a integrated UI is that it makes it more modular and easier to customise.
Maybe you have a good idea for another interactive widget? Maybe you can do cool stuff with different libraries? The idea is that you can do this very easily since you just have to write a function that works with the xarray data.
How do I learn this? A good starting point is to have a look at the source files of data explorer. The source files in data explorer are designed to be simple and small: each one contains one (or maybe two) simple functions.
Also, as I develop the source files in the Jupyter notebook interface, I also typically debug and test them directly in the source file while I'm working. How does this work? If you open the .py
file in the notebook server, then it will look like just a regular notebook. The debugging code is at the bottom in a markdown cell (which gets converted to a special commented region of the code when you save). Simply convert that from a markdown cell to a code cell, and then you can directly in the running kernel debug the function as you develop it. When you're done, simply convert back to a markdown cell and it's ready to be used as a python module.