|
Plotting of Acquired Data using Bokeh |
Tags | visualise☁plot☁single |
Digital sensors, like the ones used in PLUX acquisition systems, establish an interface between physical and digital environment.
The human sensorial system is analogous to this description, being the visual component particularly important for a researcher, in order to extract knowledge from the acquired data. Plotting data brings another perspective to the researcher, stimulating this sensorial component, which is ideal for identifying patterns and communicate.
This Jupyter Notebook is intended to explain how the user can plot data in a simple and attractive way.
1 - Importation of the needed packages
# Base packages used in OpenSignals Tools Notebooks for plotting data
from bokeh.plotting import figure, show
from bokeh.io import output_notebook
from bokeh.layouts import gridplot
from bokeh.models.tools import *
output_notebook(hide_banner=True)
# Package for ensuring operations in arrays
from numpy import average, linspace, random
# Own opensignalstools package needed here for applying the default OpenSignals styles and for loading data from an acquisition
# file.
import biosignalsnotebooks as bsnb
2 - Load of data using load function of biosignalsnotebooks package
# Load of data from a remote source
data, header = bsnb.load("/signal_samples/ecg_sample.h5", get_header=True)
print ("\033[1mHeader:\n\033[0m" + str(header) + "\n\033[1mData:\033[0m\n" + str(data))
3 - Storage of CH1 data in a dedicated variable and creation of a time axis linked with the acquired data
signal = data["CH1"]
time = bsnb.generate_time(signal, header["sampling rate"])
4 - Creation of an auxiliary signal by adding noise to the original one
# Noise samples and change of the baseline level
baseline = average(signal)
baseline_shift = 0.50 * baseline
data_noise = signal + random.normal(0, 1000, len(signal)) + baseline_shift
5 - Creation of a figure to plot the acquired data
# New Bokeh figure.
bokeh_figure = figure(x_axis_label='Time (s)', y_axis_label='Raw Data')
6 - Plotting of data in the last created figure (adding the respective legend of the axes with the "legend_label" argument)
# Original Data.
bokeh_figure.line(time, signal, legend_label="Original Data")
# Noisy Data.
bokeh_figure.line(time, data_noise, legend_label="Noisy Data")
Bokeh offers lots of configurable options. When invoking line function arguments can be specified for customising the plot, such as the next ones:
Argument | Input type |
line_width | numeric |
line_color |
RGB hexadecimal values;
bokeh.colors.RGB objects; CSS-format RGB/RGBA strings |
line_dash | line style such as dotted or dashed |
7 - Show figure
Bokeh offers the user interactive tools in right panel, for panning or zooming the representationshow(bokeh_figure)
Sometimes may be interesting that plots be represented in separate axes. This can be achieved by creating multiple figures. When a figure is created hits handler needs to be stored in a variable, in order to plot all the desired data by invoking the figure.
When all figures have been "filled" a Grid Layout is defined, as described in the following steps.
E.1 - Creation of two separate figures
# Top Figure.
top_figure = figure(x_axis_label='Time (s)', y_axis_label='Raw Data')
# Bottom Figure.
bottom_figure = figure(x_axis_label='Time (s)', y_axis_label='Raw Data')
E.2 - Plotting of data in each figure
# Plot of data in top_figure.
top_figure.line(time, signal, legend_label="Original Data")
# Plot of data in bottom_figure.
bottom_figure.line(time, data_noise, legend_label="Noisy Data")
E.3 - Generation of the Grid Plot structure
In this case we want a grid with 2x1 shape (2 lines and 1 column), so the gridplot input will be [[top_figure], [bottom_figure]].grid_plot = gridplot([[top_figure], [bottom_figure]])
E.4 - Show the final Grid Plot
show(grid_plot)
Some of these visualisation functionalities can be done in a more immediate way by
plot
function of
biosignalsnotebooks
package.
For example to produce a similar result of steps 1 to 7 the command should be:
bsnb.plot([time, time], [signal, data_noise], legend_label=["Original Data", "Noisy Data"], y_axis_label=["Raw Data", "Raw Data"], x_axis_label="Time (s)")
To produce the result of steps E.1 to E.3:
bsnb.plot([time, time], [signal, data_noise], legend_label=["Original Data", "Noisy Data"], y_axis_label=["Raw Data", "Raw Data"], grid_plot=True, grid_lines=2, grid_columns=1, x_axis_label="Time (s)")
In a scientific research, graphical representations of collected data or time-series describing the evolution of extracted parameters is essential to achieve a better knowledge of the phenomenon under analysis, considering that a graphical plot is much more intuitive than raw numerical data.
As you can see, generating interactive and attractive plots is easy and now you have an additional tools to explore with the Bokeh package.
We hope that you have enjoyed this guide. biosignalsnotebooks is an environment in continuous expansion, so don"t stop your journey and learn more with the remaining Notebooks !