Spaces:
Sleeping
Sleeping
File size: 2,500 Bytes
de6f1e8 60034d4 010071f b8b8eab de6f1e8 010071f 60034d4 de6f1e8 b8b8eab de6f1e8 60034d4 de6f1e8 b8b8eab de6f1e8 60034d4 de6f1e8 60034d4 b8b8eab de6f1e8 60034d4 b04cfbb de6f1e8 60034d4 de6f1e8 60034d4 b8b8eab de6f1e8 b8b8eab 60034d4 de6f1e8 60034d4 b8b8eab 60034d4 de6f1e8 60034d4 de6f1e8 60034d4 de6f1e8 60034d4 |
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 |
# tools/plot_generator.py
import os
import tempfile
import pandas as pd
import plotly.graph_objects as go
from typing import Tuple, Union
def plot_metric_tool(
file_path: str,
date_col: str,
value_col: str,
output_dir: str = "/tmp",
title: str = None,
line_width: int = 2,
marker_size: int = 6
) -> Union[Tuple[go.Figure, str], str]:
"""
Load CSV or Excel file, parse a time series metric, and return an interactive Plotly Figure
plus a high-res PNG file path for static embedding.
Returns:
- (fig, img_path) on success
- error string starting with 'β' on failure
"""
# Load data
ext = os.path.splitext(file_path)[1].lower()
try:
df = pd.read_excel(file_path) if ext in ('.xls', '.xlsx') else pd.read_csv(file_path)
except Exception as exc:
return f"β Failed to load file: {exc}"
# Validate columns
missing = [c for c in (date_col, value_col) if c not in df.columns]
if missing:
return f"β Missing column(s): {', '.join(missing)}"
# Parse and clean
try:
df[date_col] = pd.to_datetime(df[date_col], errors='coerce')
except Exception:
return f"β Could not parse '{date_col}' as dates."
df[value_col] = pd.to_numeric(df[value_col], errors='coerce')
df = df.dropna(subset=[date_col, value_col])
if df.empty:
return f"β No valid data after cleaning '{date_col}'/'{value_col}'"
# Aggregate duplicates and sort
df = (
df[[date_col, value_col]]
.groupby(date_col, as_index=True)
.mean()
.sort_index()
)
# Build figure
fig = go.Figure(
data=[
go.Scatter(
x=df.index,
y=df[value_col],
mode='lines+markers',
line=dict(width=line_width),
marker=dict(size=marker_size),
name=value_col,
)
]
)
fig.update_layout(
title=title or f"{value_col} Trend",
xaxis_title=date_col,
yaxis_title=value_col,
template='plotly_dark',
hovermode='x unified'
)
# Save PNG
os.makedirs(output_dir, exist_ok=True)
tmp = tempfile.NamedTemporaryFile(suffix='.png', prefix='trend_', dir=output_dir, delete=False)
img_path = tmp.name
tmp.close()
try:
fig.write_image(img_path, scale=2)
except Exception as exc:
return f"β Failed saving image: {exc}"
return fig, img_path
|