Desktop application to interactively visualize and correct the variables
of a data file (csv / xlsx / parquet), with event overlays and saving to
<name>_corrected.<extension>.
Originally created for BVECSM (Bassin Versant Expérimental Campus Sainte-Marthe, an experimental research watershed) to manually correct environmental sensor time series (temperature, water level, soil moisture, etc.) before further processing, but usable for any timestamped tabular data. Author: Maxime Tarka. See LICENSE (MIT).
Download the latest ready-to-use archive from the
Releases page, unzip it anywhere, then double-click
run_app.bat. That's it — no Python installation, no PowerShell script to
run, nothing to build. The archive already contains everything needed
(embedded Python runtime + app).
This repository contains the application source code (app/). The
embedded Python runtime and the development environment (.venv/) are
not versioned; the .ps1 scripts below are for the maintainer building a
release, not for end users.
- Windows, no Python installed: run
powershell -ExecutionPolicy Bypass -File setup\setup_runtime.ps1to download an embeddable Python and install dependencies intoruntime/, then launch withrun_app.bat. - With Python 3.12 already installed: create a virtual environment and
install the dependencies listed in
setup/requirements.txt, then runpython app/main.py.
To build a ready-to-share archive (embedded runtime, without dev files),
see setup/package_app.ps1 and RELEASING.md.
Double-click the desktop shortcut "Correction series temporelles",
or run run_app.bat directly.
- "Open a data file...": opens a data file (
.csv,.xlsx,.parquet). The timestamp column is detected automatically (by column name, or by its data type). - "Time axis": shows which column is used as the X axis (time). It defaults to the automatically detected column, but you can pick any other column from the dropdown if the detection picked the wrong one. Whichever column is selected as the time axis is removed from the "Variable" list (it cannot be corrected as a variable itself).
- "Open an events file...": opens an events file (punctual annotations or time periods), shown as an overlay on the plot.
- The "Variable" dropdown lists all variables available in the file; selecting one plots it.
- The "Display" dropdown lets you choose to show:
- Raw: the raw curve (original data, never modified).
- Corrected: the corrected curve (with applied edits).
- Both: both curves overlaid.
- "Show events": shows/hides event markers (vertical lines or colored bands) loaded from the events file. Hovering over an event shows its details in a tooltip.
- When hovering the mouse over the plot:
- the cursor's x; y coordinates are shown in the top-right corner.
- when the cursor is near a data point, a yellow marker appears on that point.
- Navigating the plot:
- click and drag (left mouse button) to pan the view.
- scroll wheel to zoom in/out.
- "Y range": lets you type a precise Y-axis range, applied with the "Apply" button.
- "Auto (data)": automatically fits the view to the data extent.
- "Previous view": returns to the previous view.
The "Selection" toolbar offers several modes (only one active at a time):
- Point: click on the plot to select the nearest data point.
- X range: an adjustable vertical band (drag its edges) selects all points within that time range.
- Y range: an adjustable horizontal band selects all points whose Y value falls within that range.
- X/Y rectangle: two clicks (two opposite corners) define a rectangle; all points inside it are selected.
- "Clear selection": clears the current selection.
Selected points are highlighted as an overlay on the plot (a selection is required to apply most corrections below).
In the "Corrections" panel, click the desired correction type to show its parameter form, then click "Apply":
- Delete: removes the selected points (sets them to
NaN). - Replace with a value: replaces the selected points with a fixed value.
- Offset (+/-): adds (or subtracts) a constant value to the selected points.
- Multiply: multiplies the selected points by a factor.
- Custom expression: applies a math formula to the selected points.
xrepresents the selected value(s). See Expression syntax below for the full list of supported operators and functions.- The "Insert hovered value from the plot" button directly inserts into the formula the Y value of the point hovered/clicked on the plot (handy for calibrating a correction from a value read off the plot).
- Threshold / min-max range: does not require a selection — scans the
whole variable and acts on points whose value is outside (or inside) a
Minimum/Maximumrange. The action to apply (delete, replace, offset, multiply, expression) is chosen in the "Action" dropdown.
The "Apply automatically to selection" checkbox applies the armed correction as soon as a new selection is made, without needing to click "Apply" each time.
The "Custom expression" correction and the "Threshold / min-max
range" correction (when its action is set to "Custom expression") both
evaluate a standard Python/numpy formula. x is the selected value(s)
(a number or array), and np (numpy) is available for math functions.
| You want... | Write it as |
|---|---|
| Addition / subtraction | x + 1, x - 3 |
| Multiplication / division | x * 2, x / 2 |
| Power (e.g. x²) | x**2 |
| Square root | np.sqrt(x) |
| Exponential (e^x) | np.exp(x) |
| Natural log (ln) | np.log(x) |
| Log base 10 | np.log10(x) |
| Log base 2 | np.log2(x) |
| Absolute value | np.abs(x) |
| Sine / cosine / tangent (radians) | np.sin(x), np.cos(x), np.tan(x) |
| Convert degrees to radians | np.radians(x) |
| Rounding | np.round(x), np.floor(x), np.ceil(x) |
| Combine operations (parentheses) | (x - 3) / 2, np.exp(np.log(x) * 2) |
Notes:
**is the power operator (not^).- Functions that aren't basic arithmetic must be prefixed with
np.(e.g.np.exp(x), notexp(x)). - Standard operator precedence applies:
np.exp(x) + 1computese^x + 1, note^(x+1)— use parentheses to be explicit:np.exp(x + 1).
The "Detection" panel offers two automatic detectors:
- Detect spikes: finds punctual outliers (spikes), based on a sliding window and a z-score threshold.
- Detect frozen (stuck) values: finds runs of identical consecutive values (stuck sensor), based on a minimum run length and a tolerance.
For each detector:
- Adjust the parameters if needed.
- Click "Detect": candidate points are highlighted on the plot and their count is shown ("Candidates: N").
- "Select candidates": turns the detected candidates into a selection, so a correction (e.g. "Delete") can be applied to them.
- "Clear": clears the detection results.
The "History" panel lists all corrections applied to the current variable, in order:
- "Undo last correction": undoes the most recently applied correction.
- "Delete selected correction": removes a specific correction from the history (even if it's not the last one); later corrections are automatically recomputed.
- "Restore deleted correction": restores the last correction removed with the button above.
- "Revert to raw data": undoes all corrections for the variable and reverts to the original raw data (with confirmation).
The "Save as" dropdown lets you choose the output file format: Parquet (.parquet), CSV (.csv) or Excel (.xlsx).
The Save button offers 3 outputs, each written to a different file next to the opened file. Click the button itself to write all 3 at once, or open its menu to write just one:
-
<name>_corrected.<extension>("diff"): only the rows that actually changed (a value equal to raw is never included), only the touched columns. This is the file meant to be uploaded to the website's manual-correction page. -
<name>_corrected_serie.<extension>("series"): the full series (all rows), only the touched column(s) — for working on the series as a whole. -
<name>_corrected_full.<extension>("full"): the full table, all columns, all rows — today's original save behavior. -
The original file is never modified.
-
If an output file already exists (for the chosen format), the new corrections are merged with previously saved corrections for other variables in that same file.
-
When re-opening a file (whether it's a
_corrected*.*file or not), the "Raw" and "Corrected" curves always start identical: no previous correction is automatically pre-applied to the displayed "Corrected" curve.
The "Dark mode" / "Light mode" button in the top bar switches the whole interface's theme. The choice is remembered between sessions.
- Application logs are in
app\logs\app.log. - Unhandled errors (crashes) are written to
app\logs\crash.log.
Application desktop pour visualiser et corriger interactivement les
variables d'un fichier de données (csv / xlsx / parquet), avec
superposition d'événements et sauvegarde dans <nom>_corrected.<extension>.
Créée à l'origine pour le BVECSM (Bassin Versant Expérimental Campus Sainte-Marthe, un bassin versant expérimental de recherche) pour corriger manuellement des séries temporelles de capteurs environnementaux (température, niveau d'eau, humidité du sol, etc.) avant traitement, mais utilisable pour tout jeu de données tabulaires horodatées. Auteur : Maxime Tarka. Voir LICENSE (MIT).
Télécharger la dernière archive prête à l'emploi depuis la
page Releases, la décompresser n'importe où, puis
double-cliquer sur run_app.bat. C'est tout — pas d'installation de
Python, pas de script PowerShell à exécuter, rien à compiler. L'archive
contient déjà tout le nécessaire (runtime Python embarqué + application).
Ce dépôt contient le code source de l'application (app/). Le runtime
Python embarqué et l'environnement de développement (.venv/) ne sont pas
versionnés ; les scripts .ps1 ci-dessous sont pour le mainteneur qui
prépare une release, pas pour les utilisateurs finaux.
- Windows, sans Python installé : exécuter
powershell -ExecutionPolicy Bypass -File setup\setup_runtime.ps1pour télécharger un Python embarqué et installer les dépendances dansruntime/, puis lancer avecrun_app.bat. - Avec Python 3.12 déjà installé : créer un environnement virtuel et
installer les dépendances listées dans
setup/requirements.txt, puis lancerpython app/main.py.
Pour créer une archive prête à distribuer (runtime embarqué, sans les
fichiers de dev), voir setup/package_app.ps1 et
RELEASING.md.
Double-cliquer sur le raccourci Bureau "Correction series temporelles",
ou directement sur run_app.bat.
- "Open a data file..." : ouvre un fichier de données (
.csv,.xlsx,.parquet). La colonne de temps est détectée automatiquement (par nom de colonne, ou par son type de données). - "Time axis" : indique quelle colonne est utilisée comme axe X (temps). Par défaut, c'est la colonne détectée automatiquement, mais on peut choisir n'importe quelle autre colonne dans le menu si la détection automatique s'est trompée. La colonne sélectionnée comme axe X est retirée de la liste "Variable" (elle ne peut pas être corrigée en tant que variable).
- "Open an events file..." : ouvre un fichier d'événements (annotations ponctuelles ou périodes), affichées en surimpression sur le graphe.
- Le menu "Variable" liste toutes les variables disponibles dans le fichier ; en choisir une affiche son graphe.
- Le menu "Display" permet de choisir d'afficher :
- Raw : la courbe brute (données d'origine, jamais modifiées).
- Corrected : la courbe corrigée (avec les modifications appliquées).
- Both : les deux superposées.
- "Show events" : affiche/masque les marqueurs d'événements (lignes verticales ou bandes colorées) chargés depuis le fichier d'événements. Passer la souris sur un événement affiche son détail (infobulle).
- En passant la souris sur le graphe :
- les coordonnées x ; y du curseur s'affichent dans le coin supérieur droit.
- lorsque le curseur est proche d'un point de donnée, un marqueur jaune apparaît sur ce point.
- Navigation dans le graphe :
- glisser-déposer (clic gauche maintenu) pour déplacer la vue.
- molette pour zoomer/dézoomer.
- "Y range" : permet de saisir manuellement un intervalle Y précis, avec un bouton "Apply".
- "Auto (data)" : recadre automatiquement la vue sur l'étendue des données.
- "Previous view" : revient à la vue précédente.
La barre "Selection" propose plusieurs modes (un seul actif à la fois) :
- Point : clic sur le graphe pour sélectionner le point de donnée le plus proche.
- X range : une zone verticale ajustable (glisser ses bords) sélectionne tous les points dans cet intervalle de temps.
- Y range : une zone horizontale ajustable sélectionne tous les points dont la valeur Y est dans cet intervalle.
- X/Y rectangle : deux clics (deux coins opposés) définissent un rectangle ; tous les points à l'intérieur sont sélectionnés.
- "Clear selection" : efface la sélection courante.
Les points sélectionnés sont mis en évidence en surimpression sur le graphe (la sélection est nécessaire pour appliquer la plupart des corrections ci-dessous).
Dans le panneau "Corrections", cliquer sur le type de correction souhaité pour afficher son formulaire de paramètres, puis sur "Apply" :
- Delete : supprime les points sélectionnés (mis à
NaN). - Replace with a value : remplace les points sélectionnés par une valeur fixe.
- Offset (+/-) : ajoute (ou soustrait) une valeur constante aux points sélectionnés.
- Multiply : multiplie les points sélectionnés par un facteur.
- Custom expression : applique une formule mathématique aux points
sélectionnés.
xreprésente la/les valeur(s) sélectionnée(s). Voir Syntaxe des expressions ci-dessous pour la liste complète des opérateurs et fonctions disponibles.- Le bouton "Insert hovered value from the plot" insère directement dans la formule la valeur Y du point survolé/cliqué sur le graphe (pratique pour calibrer une correction à partir d'une valeur lue sur le graphe).
- Threshold / min-max range : ne nécessite pas de sélection — analyse
toute la variable et agit sur les points dont la valeur est en dehors
(ou à l'intérieur) d'un intervalle
Minimum/Maximum. L'action à appliquer (suppression, remplacement, décalage, multiplication, expression) se choisit dans le menu "Action".
La case "Apply automatically to selection" applique la correction armée dès qu'une nouvelle sélection est faite, sans avoir à cliquer sur "Apply" à chaque fois.
La correction "Custom expression" et la correction "Threshold /
min-max range" (lorsque son action est réglée sur "Custom expression")
évaluent toutes les deux une formule Python/numpy standard. x représente
la/les valeur(s) sélectionnée(s) (un nombre ou un tableau), et np
(numpy) est disponible pour les fonctions mathématiques.
| Pour faire... | Écrire... |
|---|---|
| Addition / soustraction | x + 1, x - 3 |
| Multiplication / division | x * 2, x / 2 |
| Puissance (ex. x²) | x**2 |
| Racine carrée | np.sqrt(x) |
| Exponentielle (e^x) | np.exp(x) |
| Logarithme naturel (ln) | np.log(x) |
| Logarithme base 10 | np.log10(x) |
| Logarithme base 2 | np.log2(x) |
| Valeur absolue | np.abs(x) |
| Sinus / cosinus / tangente (radians) | np.sin(x), np.cos(x), np.tan(x) |
| Conversion degrés vers radians | np.radians(x) |
| Arrondi | np.round(x), np.floor(x), np.ceil(x) |
| Combiner des opérations (parenthèses) | (x - 3) / 2, np.exp(np.log(x) * 2) |
Remarques :
**est l'opérateur de puissance (et non^).- Les fonctions autres que les opérations arithmétiques de base doivent
être préfixées par
np.(ex.np.exp(x), et nonexp(x)). - La priorité des opérateurs standard s'applique :
np.exp(x) + 1calculee^x + 1, et none^(x+1)— utiliser des parenthèses pour être explicite :np.exp(x + 1).
Le panneau "Detection" propose deux détecteurs automatiques :
- Detect spikes : repère les valeurs aberrantes ponctuelles (pics), selon une fenêtre glissante et un seuil de z-score.
- Detect frozen (stuck) values : repère les séries de valeurs identiques (capteur figé), selon un nombre minimal de points consécutifs et une tolérance.
Pour chaque détecteur :
- Ajuster les paramètres si besoin.
- Cliquer sur "Detect" : les points candidats sont mis en évidence sur le graphe et leur nombre s'affiche ("Candidates: N").
- "Select candidates" : transforme les candidats détectés en sélection, pour pouvoir leur appliquer une correction (ex : "Delete").
- "Clear" : efface les résultats de détection.
Le panneau "History" liste toutes les corrections appliquées à la variable courante, dans l'ordre :
- "Undo last correction" : annule la dernière correction appliquée.
- "Delete selected correction" : supprime une correction précise dans l'historique (même si elle n'est pas la dernière) ; les corrections suivantes sont automatiquement recalculées.
- "Restore deleted correction" : rétablit la dernière correction supprimée via le bouton précédent.
- "Revert to raw data" : annule toutes les corrections de la variable et revient aux données brutes d'origine (avec confirmation).
Le menu "Save as" permet de choisir le format du fichier de sortie : Parquet (.parquet), CSV (.csv) ou Excel (.xlsx).
Le bouton Save propose 3 sorties, chacune écrite dans un fichier différent à côté du fichier ouvert. Cliquer sur le bouton lui-même écrit les 3 d'un coup, ou ouvrir son menu pour n'en écrire qu'une seule :
-
<nom>_corrected.<extension>("diff") : uniquement les lignes qui ont réellement changé (une valeur égale au brut n'est jamais incluse), uniquement les colonnes touchées. C'est le fichier destiné à être téléversé sur la page de correction manuelle du site web. -
<nom>_corrected_serie.<extension>("series") : la série complète (toutes les lignes), uniquement la/les colonne(s) touchée(s) — pour travailler sur la série dans son ensemble. -
<nom>_corrected_full.<extension>("full") : la table complète, toutes les colonnes, toutes les lignes — le comportement d'origine. -
Le fichier d'origine n'est jamais modifié.
-
Si un fichier de sortie existe déjà (pour le format choisi), les nouvelles corrections sont fusionnées avec les corrections précédemment enregistrées pour les autres variables de ce même fichier.
-
À la ré-ouverture d'un fichier (qu'il soit
_corrected*.*ou non), les courbes "Raw" et "Corrected" démarrent toujours identiques : aucune correction précédente n'est pré-appliquée automatiquement à la courbe "Corrected" affichée.
Le bouton "Dark mode" / "Light mode" dans la barre du haut bascule le thème de toute l'interface. Le choix est mémorisé entre les sessions.
- Les logs applicatifs sont dans
app\logs\app.log. - Les erreurs non gérées (crash) sont écrites dans
app\logs\crash.log.