Spaces:
Runtime error
Runtime error
Update visualization.py
Browse files- visualization.py +0 -95
visualization.py
CHANGED
|
@@ -127,101 +127,6 @@ def plot_mse(df, mse_values, title, color='navy', time_threshold=3, anomaly_thre
|
|
| 127 |
plt.close()
|
| 128 |
return fig, anomaly_frames
|
| 129 |
|
| 130 |
-
def plot_combined_mse(df, mse_embeddings, mse_posture, mse_voice, title, anomaly_threshold=4, time_threshold=3):
|
| 131 |
-
plt.figure(figsize=(16, 8), dpi=300)
|
| 132 |
-
fig, ax = plt.subplots(figsize=(16, 8))
|
| 133 |
-
|
| 134 |
-
if 'Seconds' not in df.columns:
|
| 135 |
-
df['Seconds'] = df['Timecode'].apply(
|
| 136 |
-
lambda x: sum(float(t) * 60 ** i for i, t in enumerate(reversed(x.split(':')))))
|
| 137 |
-
|
| 138 |
-
# Ensure the lengths of the DataFrame and MSE values are consistent
|
| 139 |
-
min_length = min(len(df), len(mse_embeddings), len(mse_posture), len(mse_voice))
|
| 140 |
-
df = df.iloc[:min_length].copy()
|
| 141 |
-
mse_embeddings = mse_embeddings[:min_length]
|
| 142 |
-
mse_posture = mse_posture[:min_length]
|
| 143 |
-
mse_voice = mse_voice[:min_length]
|
| 144 |
-
|
| 145 |
-
# Remove NaN values
|
| 146 |
-
valid_mask = ~np.isnan(mse_embeddings) & ~np.isnan(mse_posture) & ~np.isnan(mse_voice)
|
| 147 |
-
df = df[valid_mask]
|
| 148 |
-
mse_embeddings = mse_embeddings[valid_mask]
|
| 149 |
-
mse_posture = mse_posture[valid_mask]
|
| 150 |
-
mse_voice = mse_voice[valid_mask]
|
| 151 |
-
|
| 152 |
-
# Function to identify continuous segments
|
| 153 |
-
def get_continuous_segments(seconds, values, max_gap=1):
|
| 154 |
-
segments = []
|
| 155 |
-
current_segment = []
|
| 156 |
-
for i, (sec, val) in enumerate(zip(seconds, values)):
|
| 157 |
-
if not current_segment or (sec - current_segment[-1][0] <= max_gap):
|
| 158 |
-
current_segment.append((sec, val))
|
| 159 |
-
else:
|
| 160 |
-
segments.append(current_segment)
|
| 161 |
-
current_segment = [(sec, val)]
|
| 162 |
-
if current_segment:
|
| 163 |
-
segments.append(current_segment)
|
| 164 |
-
return segments
|
| 165 |
-
|
| 166 |
-
# Scale all MSE values to the same range (0 to 1)
|
| 167 |
-
def scale_mse(mse_values):
|
| 168 |
-
min_val = np.min(mse_values)
|
| 169 |
-
max_val = np.max(mse_values)
|
| 170 |
-
return (mse_values - min_val) / (max_val - min_val)
|
| 171 |
-
|
| 172 |
-
mse_embeddings_scaled = scale_mse(mse_embeddings)
|
| 173 |
-
mse_posture_scaled = scale_mse(mse_posture)
|
| 174 |
-
mse_voice_scaled = scale_mse(mse_voice)
|
| 175 |
-
|
| 176 |
-
# Plot each data series
|
| 177 |
-
for mse_values, color, label in zip([mse_embeddings_scaled, mse_posture_scaled, mse_voice_scaled],
|
| 178 |
-
['navy', 'purple', 'green'],
|
| 179 |
-
['Facial Features', 'Body Posture', 'Voice']):
|
| 180 |
-
segments = get_continuous_segments(df['Seconds'], mse_values)
|
| 181 |
-
|
| 182 |
-
for segment in segments:
|
| 183 |
-
segment_seconds, segment_mse = zip(*segment)
|
| 184 |
-
ax.scatter(segment_seconds, segment_mse, color=color, alpha=0.3, s=5, label=label if segment == segments[0] else "")
|
| 185 |
-
|
| 186 |
-
if len(segment) > 1:
|
| 187 |
-
segment_df = pd.DataFrame({'Seconds': segment_seconds, 'MSE': segment_mse})
|
| 188 |
-
segment_df = segment_df.sort_values('Seconds')
|
| 189 |
-
mean = segment_df['MSE'].rolling(window=min(10, len(segment)), min_periods=1, center=True).mean()
|
| 190 |
-
std = segment_df['MSE'].rolling(window=min(10, len(segment)), min_periods=1, center=True).std()
|
| 191 |
-
|
| 192 |
-
ax.plot(segment_df['Seconds'], mean, color=color, linewidth=0.5)
|
| 193 |
-
ax.fill_between(segment_df['Seconds'], mean - std, mean + std, color=color, alpha=0.1)
|
| 194 |
-
|
| 195 |
-
# Plot median baseline for each series
|
| 196 |
-
median = np.median(mse_values)
|
| 197 |
-
ax.axhline(y=median, color=color, linestyle=':', alpha=0.5, label=f'{label} Baseline Median')
|
| 198 |
-
|
| 199 |
-
# Plot threshold for each series
|
| 200 |
-
threshold = np.mean(mse_values) + anomaly_threshold * np.std(mse_values)
|
| 201 |
-
ax.axhline(y=threshold, color=color, linestyle='--', alpha=1, label=f'{label} Anomaly Threshold')
|
| 202 |
-
|
| 203 |
-
# Plot anomalies in red
|
| 204 |
-
anomalies = mse_values > threshold
|
| 205 |
-
ax.scatter(df['Seconds'][anomalies], mse_values[anomalies], color='red', s=20, zorder=5)
|
| 206 |
-
|
| 207 |
-
max_seconds = df['Seconds'].max()
|
| 208 |
-
num_ticks = 100
|
| 209 |
-
tick_locations = np.linspace(0, max_seconds, num_ticks)
|
| 210 |
-
tick_labels = [seconds_to_timecode(int(s)) for s in tick_locations]
|
| 211 |
-
|
| 212 |
-
ax.set_xticks(tick_locations)
|
| 213 |
-
ax.set_xticklabels(tick_labels, rotation=90, ha='center', fontsize=6)
|
| 214 |
-
|
| 215 |
-
ax.set_xlabel('Timecode')
|
| 216 |
-
ax.set_ylabel('Scaled Mean Squared Error')
|
| 217 |
-
ax.set_title(title)
|
| 218 |
-
|
| 219 |
-
ax.grid(True, linestyle='--', alpha=0.7)
|
| 220 |
-
ax.legend()
|
| 221 |
-
plt.tight_layout()
|
| 222 |
-
plt.close()
|
| 223 |
-
return fig
|
| 224 |
-
|
| 225 |
|
| 226 |
def plot_mse_histogram(mse_values, title, anomaly_threshold, color='blue'):
|
| 227 |
plt.figure(figsize=(16, 3), dpi=300)
|
|
|
|
| 127 |
plt.close()
|
| 128 |
return fig, anomaly_frames
|
| 129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
|
| 131 |
def plot_mse_histogram(mse_values, title, anomaly_threshold, color='blue'):
|
| 132 |
plt.figure(figsize=(16, 3), dpi=300)
|