This tool is for research and educational purposes only. It is NOT a medical device and has NOT been validated for clinical diagnosis or treatment decisions.
Do not adjust medications, change diet, or make health decisions based solely on this output. Exercise caution and always consult a qualified healthcare professional for interpretation of glucose data and any treatment adjustments.
This tool generates a comprehensive Ambulatory Glucose Profile (AGP) with extended clinical metrics, including Time in Tight Range (TITR) metric. It processes continuous glucose monitoring (CGM) data and produces both a visual AGP plot and detailed statistical analysis.
This application should work with data from any CGM, however it was only tested with Sibionics GS1. For other models we need more data.
- Full AGP visualization with percentile curves (5-95%, IQR)
- Rate of Change (ROC) profile
- Circadian binning for time-of-day patterns
- Circadian glucose heatmap
- TIR (70-180 mg/dL)
- TITR (70-140 mg/dL) - Tight target
- TAR with Level 1 (181-250) and Level 2 (>250)
- TBR with Level 1 (54-69) and Level 2 (<54)
- MAGE (Mean Amplitude of Glycemic Excursions)
- MODD (Mean of Daily Differences)
- CONGA (Continuous Overall Net Glycemic Action)
- LBGI (Low Blood Glucose Index)
- HBGI (High Blood Glucose Index)
- ADRR (Average Daily Risk Range)
- total, above range, below range
- wear time, reading frequency
Install from PyPI:
pip install agp_tool
Install from source (editable mode, recommended for development):
pip install -e .
Or install the dependencies only:
pip install -r requirements.txt
Install the build tool and build sdist + wheel:
pip install build
python -m build
The artifacts will be placed in the dist/ directory. Run twine check dist/*
to verify the distribution metadata before publishing.
Releases are published to PyPI automatically via GitHub Actions using Trusted Publishing (OIDC). To trigger a release:
- Create and push a git tag (e.g.
v1.0.0). - Create a GitHub Release from that tag.
- The
Publish to PyPIworkflow will build and upload the distribution artifacts automatically — no API token required.
agp is designed to be used both as a CLI tool and as an importable Python
library. The public entry-point is generate_report, which accepts every
option available in the CLI and returns a matplotlib.figure.Figure.
import matplotlib
matplotlib.use("Agg") # use non-interactive backend when no display is available
from agp import generate_report
# Basic call – returns a Figure and saves ambulatory_glucose_profile.png
fig = generate_report("data.csv")
# Custom thresholds, patient info, and export
fig = generate_report(
"data.xlsx",
output="my_report.png",
low_threshold=65,
high_threshold=200,
patient_name="Jane Doe",
patient_id="P-001",
doctor="Dr. Smith",
export="metrics.json",
)
# The returned Figure can be used directly with matplotlib
fig.savefig("report.png", dpi=150, bbox_inches="tight")
# Skip plot generation (returns None)
result = generate_report("data.csv", no_plot=True)
assert result is None
# Enable the circadian heatmap
fig = generate_report("data.csv", heatmap=True, heatmap_cmap="coolwarm")
# Show interactively (e.g. in a Jupyter notebook)
fig = generate_report("data.csv", show=True)generate_report does not call plt.show() or plt.close() by default,
so it is safe to use inside automated pipelines and Jupyter notebooks without
popping up GUI windows.
| Parameter | Type | Default | Description |
|---|---|---|---|
input_file |
str | (required) | Path to glucose data file |
output |
str | "ambulatory_glucose_profile.png" |
Output PNG path |
very_low_threshold |
int | 54 | Very low glucose threshold (mg/dL) |
low_threshold |
int | 70 | Low glucose threshold (mg/dL) |
high_threshold |
int | 180 | High glucose threshold (mg/dL) |
very_high_threshold |
int | 250 | Very high glucose threshold (mg/dL) |
tight_low |
int | 70 | Tight range lower limit (mg/dL) |
tight_high |
int | 140 | Tight range upper limit (mg/dL) |
bin_minutes |
int | 5 | Circadian bin size in minutes |
sensor_interval |
int | 5 | CGM sensor interval in minutes |
min_samples |
int | 5 | Minimum samples per bin |
no_plot |
bool | False |
Skip plot; return None |
verbose |
bool | False |
Print detailed progress |
export |
str | "" |
Export metrics to .json / .csv path |
config |
str|None | None |
JSON config file path (same as CLI --config) |
patient_name |
str | "Unknown" |
Patient name for report header |
patient_id |
str | "N/A" |
Patient ID for report header |
doctor |
str | "" |
Doctor name for report header |
notes |
str | "" |
Additional notes for report header |
heatmap |
bool | False |
Enable circadian glucose heatmap |
heatmap_cmap |
str | "RdYlGn_r" |
Colormap for the heatmap |
pdf |
bool | False |
Also produce a PDF alongside the PNG |
show |
bool | False |
Call plt.show() (interactive use only) |
close |
bool | False |
Call plt.close() after building figure |
pip install -r requirements.txt
Dependencies include pandas, numpy, matplotlib, openpyxl (xlsx), xlrd (xls), odfpy (ods), Pillow (image reading), and fpdf2 (PDF generation).
Supported file formats:
| Extension | Format |
|---|---|
.xlsx |
Excel 2007+ |
.xls |
Excel 97-2003 |
.csv |
Comma-separated values |
.ods |
OpenDocument Spreadsheet |
- Date time
- Sensor Reading(mg/dL): numeric glucose values
usage: agp_tool [-h] [--output OUTPUT] [--very-low-threshold VERY_LOW_THRESHOLD] [--low-threshold LOW_THRESHOLD] [--high-threshold HIGH_THRESHOLD]
[--very-high-threshold VERY_HIGH_THRESHOLD] [--tight-low TIGHT_LOW] [--tight-high TIGHT_HIGH] [--bin-minutes BIN_MINUTES]
[--sensor-interval SENSOR_INTERVAL] [--min-samples MIN_SAMPLES] [--no-plot] [--verbose] [--export EXPORT] [--config CONFIG] [--version]
[--patient-name PATIENT_NAME] [--patient-id PATIENT_ID] [--doctor DOCTOR] [--notes NOTES] [--heatmap] [--heatmap-cmap HEATMAP_CMAP]
[--pdf]
input_file
Generate Ambulatory Glucose Profile from sensor data
positional arguments:
input_file Path to glucose data file (.xlsx, .xls, .csv, .ods)
options:
-h, --help show this help message and exit
--output, -o OUTPUT Output PNG filename (default: ambulatory_glucose_profile.png)
--very-low-threshold VERY_LOW_THRESHOLD
Very low glucose threshold in mg/dL (default: 54)
--low-threshold LOW_THRESHOLD
Low glucose threshold in mg/dL (default: 70)
--high-threshold HIGH_THRESHOLD
High glucose threshold in mg/dL (default: 180)
--very-high-threshold VERY_HIGH_THRESHOLD
Very high glucose threshold in mg/dL (default: 250)
--tight-low TIGHT_LOW
Tight range lower limit in mg/dL (default: 70)
--tight-high TIGHT_HIGH
Tight range upper limit in mg/dL (default: 140)
--bin-minutes BIN_MINUTES
Time bin size in minutes for AGP (default: 5)
--sensor-interval SENSOR_INTERVAL
CGM Sensor interval (default: 5)
--min-samples MIN_SAMPLES
Minimum samples per bin (default: 5)
--no-plot Calculate metrics only, do not generate plot
--verbose, -v Print detailed metrics during execution
--export, -e EXPORT Export metrics to file. Use .csv or .json extension (e.g. metrics.json)
--config, -c CONFIG Configuration file with parameters
--version show program's version number and exit
--patient-name, -n PATIENT_NAME
Patient name for report header
--patient-id, -id PATIENT_ID
Patient ID for report header
--doctor, -d DOCTOR Doctor name for report header
--notes, -note NOTES Additional notes for report header
--heatmap Enable the circadian glucose heatmap (disabled by default)
--heatmap-cmap HEATMAP_CMAP
Colormap for circadian heatmap (default: RdYlGn_r, requires --heatmap)
--pdf Also produce a PDF file with the PNG embedded as an image and metadata copied from the PNG. The PDF page size matches the source PNG dimensions exactly (derived from the PNG pHYs DPI metadata, defaulting to 72 DPI), with no margins, so the image is never cropped.
Basic usage
agp_tool data.xlsx
Or with CSV/ODS input
agp_tool data.csv
agp_tool data.ods
Custom output file and thresholds
agp_tool data.xlsx -o my_agp.png --low-threshold 65 --high-threshold 200
Custom tight range and bin size
agp_tool data.xlsx --tight-low 80 --tight-high 150 --bin-minutes 10
Calculate only metrics, no plot
agp_tool data.xlsx --no-plot --verbose
Generate PNG and also export a PDF
agp_tool data.xlsx --pdf
With config file
agp_tool data.xlsx --config my_settings.json
See all options
agp_tool -h
Metric Description Clinical Target
- TIR Time in Range (70-180 mg/dL) ≥70%
- TITR Time in Tight Range (70-140 mg/dL) ≥50%
- TBR Time Below Range (<70 mg/dL) <4%
- CV Coefficient of Variation <36%
- GMI Glucose Management Indicator below 7%
- J-Index Combined mean + variability n/a
Metric Description
- MAGE Mean amplitude of glycemic excursions
- MODD Day-to-day glucose variability
- CONGA Intra-day glycemic variability (1h lag)
Metric Description
- LBGI Low Blood Glucose Index
- HBGI High Blood Glucose Index
- GRI Glycemia risk index
- ADRR Average Daily Risk Range
Metric Description Warning Threshold
- Readings/day Average daily readings <24 readings/day
- Wear time % of possible readings <70%
- Severe hypo/week Events <40 mg/dL per week n/a
Key parameters at script top:
- LOW = 70 # Lower bound standard range
- HIGH = 180 # Upper bound standard range
- TIGHT_LOW = 70 # Lower bound tight range
- TIGHT_HIGH = 140 # Upper bound tight range
- BIN_MINUTES = 5 # Time bin size for AGP
- ROC_CLIP = 10 # Rate of change physiological limit
- Minimum data: AGP typically requires ≥5 days for reliability
- Data gaps: Long gaps (>2 hours) may affect MODD and ADRR calculations
- Sensor accuracy: Assumes CGM-grade data; fingerstick data may have limitations
- MAGE calculation: Uses smoothed data; may differ from manual calculation
- TITR >50% suggests acceptable glycemic control
- TBR >4% indicates need for hypoglycemia prevention
- CV >36% suggests unstable glucose, consider variability-reducing therapy
- Nighttime patterns: Shaded area helps identify nocturnal hypoglycemia; however, a sharp "V-shaped" drop with a rapid recovery may indicate sensor compression artifact rather than true hypoglycemia
- ROC spikes indicate rapid changes; correlate with meals/exercise
- GMI < 7.0%: Suggests acceptable glycemic control (Note: GMI estimates A1c from CGM data, but may differ from lab A1c).
Continuous Glucose Monitoring (CGM) Metrics – Verified References
-
Mazze RS, Lucido D, Langer O, Hartmann K, Rodbard D.
Ambulatory glucose profile: representation of verified self-monitored blood glucose data.
Diabetes Care. 1987;10(1):111–117.
DOI: 10.2337/diacare.10.1.111 -
Mazze RS, Strock E, Wesley D, Borgman S, Morgan B, Bergenstal R, Cuddihy R.
Characterizing glucose exposure for individuals with normal glucose tolerance using continuous glucose monitoring and ambulatory glucose profile analysis.
Diabetes Technology & Therapeutics. 2008;10(3):149–159.
DOI: 10.1089/dia.2007.0293 -
Battelino T, Danne T, Bergenstal RM, et al.
Clinical Targets for Continuous Glucose Monitoring Data Interpretation: Recommendations From the International Consensus on Time in Range.
Diabetes Care. 2019;42(8):1593–1603.
DOI: 10.2337/dci19-0028
- Battelino T, Danne T, Bergenstal RM, et al.
Clinical Targets for Continuous Glucose Monitoring Data Interpretation: Recommendations From the International Consensus on Time in Range.
Diabetes Care. 2019;42(8):1593–1603.
DOI: 10.2337/dci19-0028
- Monnier L, Colette C, Wojtusciszyn A, et al.
Glycemic variability: should we and can we prevent it?
Diabetes Care. 2008;31(Suppl 2):S150–S154.
DOI: 10.2337/dc08-s241
- Bergenstal RM, Beck RW, Close KL, et al.
Glucose Management Indicator (GMI): A New Term for Estimating A1C From Continuous Glucose Monitoring.
Diabetes Care. 2018;41(11):2275–2280.
DOI: 10.2337/dc18-0734
- Wojcicki JM.
J-Index: a new proposition of the assessment of current glucose control in diabetic patients.
Hormone and Metabolic Research. 1995;27(1):41–42.
DOI: 10.1055/s-2007-979927
- Service FJ, Molnar GD, Rosevear JW, Ackerman E, Gatewood LC, Taylor WF.
Mean amplitude of glycemic excursions, a measure of diabetic instability.
Diabetes. 1970;19(9):644–655.
DOI: 10.2337/diab.19.9.644
- Molnar GD, Taylor WF, Ho MM.
Day-to-day variation of continuously monitored glycaemia: a further measure of diabetic instability.
Diabetologia. 1972;8(5):342–348.
DOI: 10.1007/BF01218495
- McDonnell CM, Donath SM, Vidmar SI, Werther GA, Cameron FJ.
A novel approach to continuous glucose analysis utilizing glycemic variation.
Diabetes Technology & Therapeutics. 2005;7(2):253–263.
DOI: 10.1089/dia.2005.7.253
- Kovatchev BP, Cox DJ, Gonder-Frederick LA, Clarke WL.
Assessment of risk for severe hypoglycemia among patients with type 1 and type 2 diabetes using self-monitoring blood glucose data.
Diabetes Care. 2001;24(11):1870–1875.
DOI: 10.2337/diacare.24.11.1870
- Kovatchev BP, Otto E, Cox D, et al.
The average daily risk range: a new measure of glycemic variability.
Diabetes Care. 2006;29(11):2272–2277.
DOI: 10.2337/dc06-1085
This project uses Black for formatting and Ruff for linting.
Install the development tools:
pip install -e ".[dev]"
Check and apply formatting:
black .
Run the linter (and auto-fix safe issues):
ruff check .
ruff check --fix .
Both tools are enforced in CI – PRs must pass black --check . and ruff check . before merging.
This project is licensed under the MIT License – see the LICENSE file for details.
