Skip to content

Commit 6796679

Browse files
authored
Merge pull request #103 from amosproj/ad_visualization
Ad visualization
2 parents c2ad407 + 2f71f46 commit 6796679

File tree

12 files changed

+5044
-2
lines changed

12 files changed

+5044
-2
lines changed

amos_team_resources/anomaly_detection/mad/anomaly_detection_plot.html

Lines changed: 3888 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 9,
6+
"id": "5682a007",
7+
"metadata": {},
8+
"outputs": [
9+
{
10+
"name": "stdout",
11+
"output_type": "stream",
12+
"text": [
13+
"Imports complete\n"
14+
]
15+
}
16+
],
17+
"source": [
18+
"import pandas as pd\n",
19+
"import numpy as np\n",
20+
"import matplotlib.pyplot as plt\n",
21+
"import sys\n",
22+
"import json\n",
23+
"from pathlib import Path\n",
24+
"\n",
25+
"# Add SDK to path\n",
26+
"SDK_PATH = Path().resolve().parents[2] / \"src\" / \"sdk\" / \"python\"\n",
27+
"sys.path.insert(0, str(SDK_PATH))\n",
28+
"\n",
29+
"from rtdip_sdk.pipelines.visualization.plotly.anomaly_detection import AnomalyDetectionPlotly\n",
30+
"from rtdip_sdk.pipelines.visualization.matplotlib.anomaly_detection import AnomalyDetectionPlot\n",
31+
"\n",
32+
"from rtdip_sdk.pipelines.anomaly_detection.spark.mad.mad_anomaly_detection import MadAnomalyDetection\n",
33+
"\n",
34+
"print(\"Imports complete\")"
35+
]
36+
},
37+
{
38+
"cell_type": "code",
39+
"execution_count": 22,
40+
"id": "9a3db7c3",
41+
"metadata": {},
42+
"outputs": [],
43+
"source": [
44+
"from pyspark.sql import SparkSession\n",
45+
"from datetime import datetime, timedelta\n",
46+
"\n",
47+
"session = SparkSession.builder.appName(\"PlotlyDemoAD\").getOrCreate()\n",
48+
"\n",
49+
"\n",
50+
"base = datetime(2024, 1, 1)\n",
51+
"\n",
52+
"data = [\n",
53+
" (base + timedelta(seconds=i), v)\n",
54+
" for i, v in enumerate(\n",
55+
" [10.0, 12.0, 10.5, 11.0, 30.0, 10.2, 9.8, 10.1, 10.3, 10.0]\n",
56+
" )\n",
57+
"]\n",
58+
"columns = [\"timestamp\", \"value\"]\n",
59+
"\n",
60+
"df = session.createDataFrame(data, columns)"
61+
]
62+
},
63+
{
64+
"cell_type": "code",
65+
"execution_count": 23,
66+
"id": "f290695a",
67+
"metadata": {},
68+
"outputs": [],
69+
"source": [
70+
"ad_scorer = MadAnomalyDetection()\n",
71+
"\n",
72+
"anoms = ad_scorer.detect(df)"
73+
]
74+
},
75+
{
76+
"cell_type": "code",
77+
"execution_count": 24,
78+
"id": "abca5439",
79+
"metadata": {},
80+
"outputs": [
81+
{
82+
"data": {
83+
"text/plain": [
84+
"PosixPath('anomaly_detection_plot.html')"
85+
]
86+
},
87+
"execution_count": 24,
88+
"metadata": {},
89+
"output_type": "execute_result"
90+
}
91+
],
92+
"source": [
93+
"plotly_visualizer = AnomalyDetectionPlotly(ts_data=df, ad_data=anoms, sensor_id=\"Plotly_Demo\")\n",
94+
"plotly_visualizer.plot()\n",
95+
"plotly_visualizer.save(\"anomaly_detection_plot.html\")"
96+
]
97+
}
98+
],
99+
"metadata": {
100+
"kernelspec": {
101+
"display_name": "rtdip-sdk",
102+
"language": "python",
103+
"name": "python3"
104+
},
105+
"language_info": {
106+
"codemirror_mode": {
107+
"name": "ipython",
108+
"version": 3
109+
},
110+
"file_extension": ".py",
111+
"mimetype": "text/x-python",
112+
"name": "python",
113+
"nbconvert_exporter": "python",
114+
"pygments_lexer": "ipython3",
115+
"version": "3.12.12"
116+
}
117+
},
118+
"nbformat": 4,
119+
"nbformat_minor": 5
120+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## Time Series Anomaly Visualization – Guideline
2+
3+
This visualization is used consistently across the project to answer the
4+
following standard questions for time series anomaly analysis.
5+
6+
### Standard Questions
7+
8+
1. Where in the time series do unusual deviations from typical signal behavior occur?
9+
10+
2. Do highlighted deviations appear as isolated events or as contiguous time segments?
11+
12+
3. How do highlighted deviations relate to the local signal shape
13+
(e.g., extremes, transitions, plateaus, or abrupt level changes)?
14+
15+
4. What are the exact timestamp and value of a detected anomaly when closer inspection is required?
16+
17+
### Visualization Constraints
18+
19+
- A single continuous line plot is used to show the full time series context.
20+
- Highlighted markers are overlaid directly on the signal.
21+
- No additional subplots, thresholds, or secondary axes are introduced.
22+
- The same visual encoding is used across different detection methods.
23+
- Interactive features (e.g., hover tooltips) are optional and may be used
24+
to support precise inspection of individual anomaly points without altering
25+
the overall visual structure.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2025 RTDIP
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.

src/sdk/python/rtdip_sdk/pipelines/anomaly_detection/spark/mad/mad_anomaly_detection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from pyspark.sql import DataFrame
1818
from typing import Optional, List, Union
1919

20-
from src.sdk.python.rtdip_sdk.pipelines._pipeline_utils.models import (
20+
from ...._pipeline_utils.models import (
2121
Libraries,
2222
SystemType,
2323
)

src/sdk/python/rtdip_sdk/pipelines/visualization/matplotlib/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
ModelsOverlayPlot: Overlay multiple model forecasts
3333
ForecastDistributionPlot: Box plots of forecast distributions
3434
ComparisonDashboard: Model comparison dashboard
35+
36+
AnomalyDetectionPlot: Static plot of time series with anomalies
3537
"""
3638

3739
from .forecasting import (
@@ -51,3 +53,6 @@
5153
ForecastDistributionPlot,
5254
ComparisonDashboard,
5355
)
56+
from .anomaly_detection import (
57+
AnomalyDetectionPlot
58+
)

0 commit comments

Comments
 (0)