This is the backend for the node-red visualization page.
to implement this backend
- /!\ Done but not tried /!\ Change
FLASK_HOST
attribute to0.0.0.0
, then change every MQTT msg "add iframe" and "remove iframe" with only the dash app route without theFLASK_HOST
prefix - Reverse proxy the flask server. By default the Flask server runs on port 5000. But you can change this with the
FLASK_PORT
parameter (Visualization_Controller
parameter) - Replace the
requirements.txt
by a poetry file to manage libraries installation and avoid libraries conflicts
information about the server
Visualization_Controller default values :
- BROKER="localhost"
- MQTT_PORT=1883
- FLASK_HOST="0.0.0.0"
- FLASK_PORT=5000
- SUBSCRIBER="visualization/commands"
BROKER stands for the MQTT broker address. MQTT_PORT stands for the MQTT port FLASK_HOST the Flask server IP address FLASK_PORT the Flask server port SUBSCRIBER the Visualization_Controller topic it listenned to
This is the backend for the visualization page of node-red. It contains a MQTT client that creates dynamically figure on the fly
To run this project you need to have python 3 or higher installed in your computer. You can download python from this link. Then you can install the required packages using pip by running the following command:
pip install -r requirements.txt
Same on a Planktoscope. Clone this repository into your planktoscope and with the command line install the required packages.
For the GUI you need to pull from the node-red editor the node-red-gui-refonte project from github.
To access to github from your node-red you have to go to the settings.json
of your node-red and switch the project field to true
In order to run the project you have to execute the python file controller.py
with that command :
python path/controller.py
Once it is launched you can depploy your node-red application. On depployment the front-end will ask information to the backend to initialize (world map,timeline,tables...)
This Python script implements a MQTT controller for the visualization page.
The script defines several methods related to creating different types of visualizations (e.g., scatter plots, histograms, world maps, timelines), as well as initializing data tables and information tables. These methods are called with the create_
prefix followed by the type of visualization (e.g., create_scatter_plot
, create_hist_plot
, etc.).
Here's a breakdown of the code:
- The
VisualizationController
class defines several methods:create_scatter_plot
: Creates a scatter plot with specified x and y columns.create_hist_plot
: Creates a histogram plot for the specified column.init_datatable
: Initializes the data table.init_infotable
: Initializes the information table.create_world_map
: Creates a world map visualization.create_timeline
: Creates a timeline visualization.create_defaults_plots
: Creates default plots based on a list of basic plots.
- The
on_publish
method is a callback function that prints a message when a message is published. - The
run
method:- Connects to the MQTT broker using the
connect
method. - Starts two threads: one for the MQTT controller and another for the Flask server.
- Calls the
loop_forever
method on the MQTT controller thread, which runs indefinitely.
- Connects to the MQTT broker using the
- The script defines several instance variables:
controller
: an MQTT client object.server
: a Flask server object.data_table
,info_table
, andmap
: objects always visible created on frontend initializationdf
: a dataframe that represent the last tsv file loaded
This Python module defines a class FlaskServer
for creating and managing multiple Dash applications (which are web-based visualizations) using Flask as the web server.
Here's a breakdown of the code:
Initialization
The __init__
method initializes the FlaskServer
object with an optional parameter size
, which determines how many Dash apps to create. The default size is 20.
It sets up several instance variables:
default_layout
: a basic HTML layout for all Dash apps.server
: the Flask server.apps
: a dictionary of Dash app objects, indexed by their IDs (0 tosize-1
).apps_available
: a list of available app IDs (i.e., those that are not currently running).apps_running
: a list of currently running app IDs.
Initializing the Flask Server
The init_flask_server
method creates the Flask server and initializes it with the following:
- Creates a Flask server with the name "Visualization Server".
- For each app ID from 0 to
size-1
, creates a new Dash app with that ID, sets its layout to the default layout, and adds it to theapps
dictionary. - Sets up several routes (URLs) for the Flask server:
/
: returns a basic HTML page with links to all available apps./apps
: lists all available apps, including their IDs and whether they are running or not./apps/shutdown
: shuts down an app by resetting its layout and removing it from theapps_running
list. It also adds the ID to theapps_available
list if necessary.
Getting an Available App
The get_available_app
method returns an available Dash app (i.e., one that is not currently running). If no apps are available, it returns the first app in the list (which will be reset when run).
This Python module defines two functions and a class, all related to working with TSV (Tab-Separated Values) files. Here's a breakdown of the code:
Functions
find_tsv_files(path)
:- Iterates through a directory tree starting from the given
path
. - Checks if each file is a TSV file (ending with
.tsv
) and adds its path to an empty listtsv_files
if it is. - If a file is a ZIP archive containing a TSV file, extracts the inner file's path and adds it to the list as well. The format of these paths will be
zip_file:inner_file.tsv
. - Returns the list of TSV files found.
- Iterates through a directory tree starting from the given
load_dataframe(path)
:- Initializes a
CustomDataFrame
object with the givenpath
. - Converts all column names to lowercase using the
str.lower()
method. - Drops the first row of the DataFrame (the one filled with [t] and [f]).
- Iterates through each column in the DataFrame and checks if the first value is marked as numeric (
'[f]'
). If so, converts the entire column to a numeric type usingpd.to_numeric()
. - Checks if any columns contain specific keywords (
'object_'
, but not'id'
or'label'
) and adds them to an empty listmetadatas_of_interest
. These are likely metadata columns of interest. - Returns the loaded DataFrame, its length, and the list of metadatas of interest.
- Initializes a
Class
CustomDataFrame(pd.DataFrame)
:- Defines a custom DataFrame class that inherits from Pandas' built-in
pd.DataFrame
class. - Adds three attributes:
path
,name
, andzip
. These are used to store metadata about the DataFrame, such as its file path and whether it was loaded from a ZIP archive. - Overloads the
__init__()
method to initialize the custom DataFrame with optional parameterspath
and**kwargs
. - If a
path
is provided, checks if it's a ZIP file containing an inner TSV file. If so, reads the TSV file from the ZIP archive usingzipfile.ZipFile
. Otherwise, reads the TSV file directly usingpd.read_csv()
. - Sets the
zip
attribute toTrue
if the DataFrame was loaded from a ZIP archive andFalse
otherwise. - Sets the
path
andname
attributes accordingly.
- Defines a custom DataFrame class that inherits from Pandas' built-in
- World Map: Displays a world map with markers representing datasets.
- Timeline: Datasets over time.
- Data Table: Presents object metadata in a tabular format.
- Info Table: Similar to a data table but displays metadata about the project.
- Scatter Plot: Plots data points on a 2D coordinate system (x-y axis) to show relationships between variables.
- Hist Plot: Displays the distribution of data values over a range of intervals or bins.
Structure
Each chart follows a similar structure:
- Data Preparation: Create a new Pandas DataFrame (df) if it is needed to transform the data given in input of the class that represent the tsv file
- Creation of Plotly Layout: Define the appearance of the figure, including colors, fonts, backgrounds, and more.
- Creation of Dash App: Contain the Plotly figure and add HTML/CSS elements with custom Python code to enhance the visualization and add dynamic interactions with the user.
For removable iframe : A callback function send a POST msg to the Flask server and send a MQTT msg "remove iframe" to the node-red chartPage node
Key Components
The code uses several key components:
- Dash App Framework: Manages the web application.
- Plotly Figures: Used to create visualizations, including world maps, timelines, data tables, and more.
- Pandas DataFrame: Used to store/manipulate data
- MQTT: For the MQTT interaction with the front-end