Visualization¶
Jitterbug ships a small set of matplotlib figures for looking at an analysis: the raw
and minimum RTT series, the detected change points, the congestion periods, and summary
statistics. They are available from the CLI (jitterbug visualize) and from Python
(JitterbugPlotter).
Installation¶
uv sync --extra visualization # adds matplotlib
CLI: jitterbug visualize¶
Runs the same analysis as jitterbug analyze and writes five PNG files (300 dpi):
jitterbug visualize examples/network_analysis/data/raw.csv --output-dir plots
✅ 5 plots saved to plots
• congestion_analysis: jitterbug_congestion_analysis.png
• change_points: jitterbug_change_points.png
• confidence_heatmap: jitterbug_confidence_heatmap.png
• summary_stats: jitterbug_summary_stats.png
• rtt_timeseries: jitterbug_rtt_timeseries.png
📊 Key Statistics:
• Total periods: 22
• Congested periods: 11
• Congestion ratio: 24.4%
• Change points: 24
Options:
| Option | Meaning |
|---|---|
--output-dir, -o |
Directory for the PNG files (default visualization_output) |
--prefix |
Filename prefix (default jitterbug) |
--algorithm, -a |
ruptures (default) or bcp |
--method, -m |
jitter_dispersion (default) or ks_test |
--threshold, -t |
Change point detection threshold |
--config, -c |
YAML/JSON configuration file, as for analyze |
--format, -f |
Input format (csv, json); auto-detected if omitted |
Example with the paper's configuration:
jitterbug visualize examples/network_analysis/data/raw.csv \
--algorithm bcp --method ks_test --output-dir plots_bcp --prefix bcp
The figures¶
| File | Content |
|---|---|
*_congestion_analysis.png |
Three stacked panels sharing the time axis: raw RTT, minimum RTT per interval, and the congestion verdict per period with congested spans shaded. The figure in the README is this one. |
*_change_points.png |
Minimum RTT series with a vertical line per change point, colored by confidence. |
*_confidence_heatmap.png |
Confidence of each period's verdict over time. |
*_summary_stats.png |
Counts, congestion ratio, confidence and duration distributions. |
*_rtt_timeseries.png |
Raw and minimum RTT series overlaid. |
Time axes pick their own tick spacing from the span of the data (hours to weeks).
Python: JitterbugPlotter¶
from pathlib import Path
from jitterbug import JitterbugAnalyzer, JitterbugConfig
from jitterbug.visualization import JitterbugPlotter
analyzer = JitterbugAnalyzer(JitterbugConfig())
results = analyzer.analyze_from_file("examples/network_analysis/data/raw.csv")
plotter = JitterbugPlotter() # JitterbugPlotter(style="ggplot", figsize=(14, 8)) also works
# Everything the CLI writes, in one call
paths = plotter.save_all_plots(
raw_data=analyzer.raw_data,
min_rtt_data=analyzer.min_rtt_data,
results=results,
change_points=analyzer.change_points or [],
output_dir=Path("plots"),
prefix="run1",
)
# Or one figure at a time; each method returns the matplotlib Figure
fig = plotter.plot_congestion_analysis(
analyzer.raw_data, analyzer.min_rtt_data, results, title="Path A, December 2017"
)
fig.savefig("path_a.png", dpi=300, bbox_inches="tight")
Methods, all returning a matplotlib.figure.Figure and accepting title and save_path:
| Method | Inputs |
|---|---|
plot_rtt_timeseries(datasets) |
{"label": RTTDataset, ...}; show_points=True draws markers |
plot_congestion_analysis(raw_data, min_rtt_data, results) |
the three-panel figure |
plot_change_points(dataset, change_points) |
MinimumRTTDataset and list[ChangePoint] |
plot_confidence_heatmap(results) |
CongestionInferenceResult |
plot_summary_statistics(results) |
CongestionInferenceResult |
plot_algorithm_comparison(dataset, algorithm_results) |
{"ruptures": [...], "bcp": [...]} change points per detector |
analyzer.raw_data, analyzer.min_rtt_data and analyzer.change_points are populated by
the last analyze* call.
In notebooks¶
The figures are ordinary matplotlib objects, so %matplotlib inline shows them. The two
notebooks in examples/ (jitter_dispersion_analysis.ipynb,
kolmogorov_smirnov_analysis.ipynb) build their own figures with matplotlib directly,
which is a good starting point for custom layouts.
Headless use¶
Set MPLBACKEND=Agg (or matplotlib.use("Agg") before importing the plotter) on servers
and in tests. The test suite does exactly this in tests/conftest.py.
Comparing detectors¶
tools/generate_visualizations.py runs both detectors on the bundled dataset, writes
one congestion analysis figure per detector plus a comparison chart, and regenerates
examples/network_analysis/plots/README.md. It needs the bcp extra and takes a few
seconds on CPU (see bcp_device in the configuration).
Troubleshooting¶
matplotlib not found:uv sync --extra visualization.- Blank or tiny figures in a notebook: call the plotting method after
%matplotlib inlineand do not callplt.close()before display. - Slow on very long series: the plots draw every raw sample; downsample the raw data
before plotting or plot only
min_rtt_data.