-
Notifications
You must be signed in to change notification settings - Fork 1
/
web_graph.py
283 lines (244 loc) · 10.2 KB
/
web_graph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# web_graph.py
import logging
import matplotlib
matplotlib.use('Agg') # Use a non-interactive backend
import matplotlib.pyplot as plt
import io
import base64
from datetime import datetime, timedelta
import os
import matplotlib.dates as mdates
import numpy as np
def generate_detection_graph(time_range_hours, detection_log_path):
"""Generates a histogram of detections over the specified time range with enhanced readability."""
now = datetime.now()
start_time = now - timedelta(hours=time_range_hours)
timestamps = []
# Read the detection log file
if not os.path.exists(detection_log_path):
logging.warning(f"Detection log file not found: {detection_log_path}")
return None
with open(detection_log_path, 'r') as f:
for line in f:
try:
if 'Timestamp ' in line:
timestamp_str = line.split('Timestamp ')[1].split(',')[0].strip()
detection_time = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S')
if detection_time >= start_time:
timestamps.append(detection_time)
except Exception as e:
logging.exception(f"Error parsing line: {line}")
continue
if not timestamps:
logging.info("No detection data available for the selected time range.")
return None # No data to plot
# Convert datetime to matplotlib's numerical format
dates = mdates.date2num(timestamps)
start_num = mdates.date2num(start_time)
end_num = mdates.date2num(now)
# Create the histogram
plt.figure(figsize=(12, 6))
ax = plt.gca()
# Define bin width, label, locator, and formatter based on the time range
if time_range_hours <= 1:
# For up to 1 hour, use 1-minute bins
bin_width = 1.0 / (24 * 60) # One minute in days
time_label = "Last Hour"
bin_locator = mdates.MinuteLocator(interval=5)
bin_formatter = mdates.DateFormatter('%H:%M')
elif time_range_hours <= 3:
# For up to 3 hours, use 1-minute bins
bin_width = 1.0 / (24 * 60) # One minute in days
time_label = "Last 3 Hours"
bin_locator = mdates.MinuteLocator(interval=15)
bin_formatter = mdates.DateFormatter('%H:%M')
elif time_range_hours <= 24:
# For time ranges up to 24 hours, use 5-minute bins
bin_width = 5.0 / (24 * 60) # Five minutes in days
time_label = "Last 24 Hours"
bin_locator = mdates.HourLocator(interval=1)
bin_formatter = mdates.DateFormatter('%H:%M')
elif time_range_hours <= 168: # Up to one week
# Use 6-hour bins
bin_width = 6.0 / 24 # Six hours in days
time_label = "Last Week"
bin_locator = mdates.DayLocator(interval=1)
bin_formatter = mdates.DateFormatter('%b %d')
elif time_range_hours <= 720: # Up to one month
# Use daily bins
bin_width = 1 # One day
time_label = "Last Month"
bin_locator = mdates.DayLocator(interval=1)
bin_formatter = mdates.DateFormatter('%b %d')
elif time_range_hours <= 8760: # Up to one year
# Use weekly bins
bin_width = 7 # Seven days
time_label = "Last Year"
bin_locator = mdates.MonthLocator(interval=1)
bin_formatter = mdates.DateFormatter('%b')
else:
# For longer time ranges, use monthly bins
bin_width = 30 # Approximately thirty days
time_label = "Multiple Years"
bin_locator = mdates.MonthLocator(interval=3)
bin_formatter = mdates.DateFormatter('%b %Y')
# Compute the number of bins and define bin edges
if time_range_hours <= 24:
# For up to 24 hours, use finer binning
bins = np.arange(start_num, end_num + bin_width, bin_width)
elif time_range_hours <= 168:
# For up to one week, use 6-hour bins
bins = np.arange(start_num, end_num + bin_width, bin_width)
elif time_range_hours <= 720:
# For up to one month, use daily bins
bins = np.arange(start_num, end_num + bin_width, bin_width)
elif time_range_hours <= 8760:
# For up to one year, use weekly bins
bins = np.arange(start_num, end_num + bin_width, bin_width)
else:
# For multiple years, use monthly bins
bins = np.arange(start_num, end_num + bin_width, bin_width)
# Plot histogram
plt.hist(dates, bins=bins, edgecolor='black')
# Set the x-axis formatter and locator
ax.xaxis.set_major_locator(bin_locator)
ax.xaxis.set_major_formatter(bin_formatter)
# Set x-axis limits to ensure the graph spans exactly the desired time range
ax.set_xlim(start_num, end_num)
# Improve layout and readability
plt.xticks(rotation=45, ha='right')
plt.title(f'Detections {time_label}')
plt.xlabel('Time')
plt.ylabel('Number of Detections')
plt.tight_layout()
# Save the plot to a bytes buffer
buf = io.BytesIO()
plt.savefig(buf, format='png', dpi=150) # Increased DPI for better resolution
plt.close()
buf.seek(0)
image_base64 = base64.b64encode(buf.read()).decode('ascii')
return image_base64
# # web_graph.py
# import logging
# import matplotlib
# matplotlib.use('Agg') # Use a non-interactive backend
# import matplotlib.pyplot as plt
# import io
# import base64
# from datetime import datetime, timedelta
# import time
# import os
# import matplotlib.dates as mdates
# def generate_detection_graph(time_range_hours, detection_log_path):
# """Generates a histogram of detections over the specified time range."""
# now = datetime.now()
# start_time = now - timedelta(hours=time_range_hours)
# timestamps = []
# # Read the detection log file
# if not os.path.exists(detection_log_path):
# logging.warning(f"Detection log file not found: {detection_log_path}")
# return None
# with open(detection_log_path, 'r') as f:
# for line in f:
# try:
# if 'Timestamp ' in line:
# timestamp_str = line.split('Timestamp ')[1].split(',')[0].strip()
# detection_time = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S')
# if detection_time >= start_time:
# timestamps.append(detection_time)
# except Exception as e:
# logging.exception(f"Error parsing line: {line}")
# continue
# if not timestamps:
# logging.info("No detection data available for the selected time range.")
# return None # No data to plot
# # Create the histogram
# plt.figure(figsize=(12, 6))
# ax = plt.gca()
# # Set binning
# if time_range_hours <= 24:
# # For time ranges up to 24 hours, use hourly bins
# bin_width = timedelta(hours=1)
# locator = mdates.HourLocator()
# formatter = mdates.DateFormatter('%H:%M')
# elif time_range_hours <= 168: # Up to one week
# # Use 6-hour bins
# bin_width = timedelta(hours=6)
# locator = mdates.HourLocator(interval=6)
# formatter = mdates.DateFormatter('%b %d %H:%M')
# else:
# # For longer time ranges, use daily bins
# bin_width = timedelta(days=1)
# locator = mdates.DayLocator()
# formatter = mdates.DateFormatter('%b %d')
# # Compute the number of bins
# num_bins = int((now - start_time) / bin_width)
# bins = [start_time + i * bin_width for i in range(num_bins + 1)]
# # Plot histogram
# plt.hist(timestamps, bins=bins, edgecolor='black')
# # Set the x-axis formatter and locator
# ax.xaxis.set_major_locator(locator)
# ax.xaxis.set_major_formatter(formatter)
# # Rotate x-axis labels for better readability
# plt.xticks(rotation=45, ha='right')
# plt.title(f'Detections in the Last {time_range_hours} Hours')
# plt.xlabel('Time')
# plt.ylabel('Number of Detections')
# plt.tight_layout()
# # Save the plot to a bytes buffer
# buf = io.BytesIO()
# plt.savefig(buf, format='png')
# plt.close()
# buf.seek(0)
# image_base64 = base64.b64encode(buf.read()).decode('ascii')
# return image_base64
# # # web_graph.py
# # import logging
# # import matplotlib
# # matplotlib.use('Agg') # Use a non-interactive backend
# # import matplotlib.pyplot as plt
# # import io
# # import base64
# # from datetime import datetime, timedelta
# # import time
# # import os
# # def generate_detection_graph(time_range_hours, detection_log_path):
# # """Generates a histogram of detections over the specified time range."""
# # now = datetime.now()
# # start_time = now - timedelta(hours=time_range_hours)
# # timestamps = []
# # # Read the detection log file
# # if not os.path.exists(detection_log_path):
# # # No log file exists
# # return None
# # with open(detection_log_path, 'r') as f:
# # for line in f:
# # # Example line:
# # # 2023-10-11 14:55:12,INFO - Detection: Frame 123, Timestamp 2023-10-11 14:55:12, Coordinates: (x1, y1), (x2, y2), Confidence: 0.90
# # try:
# # # Extract the timestamp after 'Timestamp '
# # if 'Timestamp ' in line:
# # timestamp_str = line.split('Timestamp ')[1].split(',')[0].strip()
# # detection_time = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S')
# # if detection_time >= start_time:
# # timestamps.append(detection_time)
# # except Exception as e:
# # logging.exception(f"Error parsing line: {line}")
# # # Skip lines that cannot be parsed
# # continue
# # if not timestamps:
# # return None # No data to plot
# # # Create the histogram
# # plt.figure(figsize=(10, 4))
# # plt.hist(timestamps, bins=24, edgecolor='black')
# # plt.title(f'Detections in the Last {time_range_hours} Hours')
# # plt.xlabel('Time')
# # plt.ylabel('Number of Detections')
# # plt.tight_layout()
# # # Save the plot to a bytes buffer
# # buf = io.BytesIO()
# # plt.savefig(buf, format='png')
# # plt.close()
# # buf.seek(0)
# # image_base64 = base64.b64encode(buf.read()).decode('ascii')
# # return image_base64