Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -5,8 +5,7 @@ import datetime
|
|
5 |
import os
|
6 |
import base64
|
7 |
from typing import List, Optional, Dict, Any
|
8 |
-
import
|
9 |
-
import matplotlib.pyplot as plt
|
10 |
import io
|
11 |
|
12 |
|
@@ -45,60 +44,119 @@ def extract_structured_data(text: str, schema: str) -> str:
|
|
45 |
|
46 |
@tool
|
47 |
def data_visualization(data: str, chart_type: str, title: str = "Data Visualization") -> str:
|
48 |
-
"""Creates a
|
49 |
|
50 |
Args:
|
51 |
-
data: JSON string
|
52 |
-
chart_type: Type of
|
53 |
title: Title for the visualization.
|
54 |
"""
|
55 |
try:
|
56 |
# Parse the input data
|
57 |
-
|
58 |
-
# Try parsing as JSON first
|
59 |
-
data_parsed = json.loads(data)
|
60 |
-
df = pd.DataFrame(data_parsed)
|
61 |
-
except:
|
62 |
-
# If not JSON, try as CSV
|
63 |
-
csv_data = io.StringIO(data)
|
64 |
-
df = pd.DataFrame.from_records(pd.read_csv(csv_data))
|
65 |
|
66 |
-
# Create appropriate
|
67 |
-
|
68 |
|
69 |
-
if chart_type.lower() == '
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
else:
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
if
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
else:
|
86 |
-
|
87 |
else:
|
88 |
-
return f"Unsupported
|
89 |
-
|
90 |
-
plt.title(title)
|
91 |
-
|
92 |
-
# Save to bytes buffer
|
93 |
-
buf = io.BytesIO()
|
94 |
-
plt.savefig(buf, format='png')
|
95 |
-
buf.seek(0)
|
96 |
-
|
97 |
-
# Convert to base64 for embedding in HTML or returning
|
98 |
-
img_str = base64.b64encode(buf.read()).decode('utf-8')
|
99 |
|
100 |
-
|
101 |
-
return f"Visualization created successfully. Image data (base64): {img_str[:30]}..."
|
102 |
except Exception as e:
|
103 |
return f"Error creating visualization: {str(e)}"
|
104 |
|
|
|
5 |
import os
|
6 |
import base64
|
7 |
from typing import List, Optional, Dict, Any
|
8 |
+
import json
|
|
|
9 |
import io
|
10 |
|
11 |
|
|
|
44 |
|
45 |
@tool
|
46 |
def data_visualization(data: str, chart_type: str, title: str = "Data Visualization") -> str:
|
47 |
+
"""Creates a textual representation of data for visualization.
|
48 |
|
49 |
Args:
|
50 |
+
data: JSON string with the data to visualize.
|
51 |
+
chart_type: Type of representation to create (summary, table, ascii).
|
52 |
title: Title for the visualization.
|
53 |
"""
|
54 |
try:
|
55 |
# Parse the input data
|
56 |
+
data_parsed = json.loads(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
+
# Create appropriate representation
|
59 |
+
result = f"=== {title} ===\n\n"
|
60 |
|
61 |
+
if chart_type.lower() == 'summary':
|
62 |
+
# Provide summary statistics
|
63 |
+
if isinstance(data_parsed, list):
|
64 |
+
result += f"Number of items: {len(data_parsed)}\n"
|
65 |
+
if len(data_parsed) > 0 and isinstance(data_parsed[0], dict):
|
66 |
+
keys = data_parsed[0].keys()
|
67 |
+
result += f"Fields: {', '.join(keys)}\n\n"
|
68 |
+
|
69 |
+
# Try to get numeric values for min/max/avg
|
70 |
+
for key in keys:
|
71 |
+
try:
|
72 |
+
values = [item[key] for item in data_parsed if isinstance(item[key], (int, float))]
|
73 |
+
if values:
|
74 |
+
result += f"{key}:\n"
|
75 |
+
result += f" Min: {min(values)}\n"
|
76 |
+
result += f" Max: {max(values)}\n"
|
77 |
+
result += f" Avg: {sum(values)/len(values):.2f}\n\n"
|
78 |
+
except (KeyError, TypeError):
|
79 |
+
pass
|
80 |
+
else:
|
81 |
+
result += f"Data summary: {str(data_parsed)[:100]}...\n"
|
82 |
+
|
83 |
+
elif chart_type.lower() == 'table':
|
84 |
+
# Create ASCII table
|
85 |
+
if isinstance(data_parsed, list) and len(data_parsed) > 0 and isinstance(data_parsed[0], dict):
|
86 |
+
# Get headers
|
87 |
+
headers = list(data_parsed[0].keys())
|
88 |
+
|
89 |
+
# Calculate column widths
|
90 |
+
col_widths = [len(h) for h in headers]
|
91 |
+
for item in data_parsed:
|
92 |
+
for i, h in enumerate(headers):
|
93 |
+
if h in item:
|
94 |
+
col_widths[i] = max(col_widths[i], len(str(item[h])))
|
95 |
+
|
96 |
+
# Create header row
|
97 |
+
header_row = " | ".join(h.ljust(col_widths[i]) for i, h in enumerate(headers))
|
98 |
+
separator = "-+-".join("-" * w for w in col_widths)
|
99 |
+
|
100 |
+
result += header_row + "\n"
|
101 |
+
result += separator + "\n"
|
102 |
+
|
103 |
+
# Create data rows
|
104 |
+
for item in data_parsed[:10]: # Limit to 10 rows for readability
|
105 |
+
row = " | ".join(str(item.get(h, "")).ljust(col_widths[i]) for i, h in enumerate(headers))
|
106 |
+
result += row + "\n"
|
107 |
+
|
108 |
+
if len(data_parsed) > 10:
|
109 |
+
result += f"\n... and {len(data_parsed) - 10} more rows"
|
110 |
else:
|
111 |
+
result += "Data is not in a format suitable for table display"
|
112 |
+
|
113 |
+
elif chart_type.lower() == 'ascii':
|
114 |
+
# Create simple ASCII chart
|
115 |
+
if isinstance(data_parsed, list):
|
116 |
+
# Try to extract x and y values
|
117 |
+
x_values = []
|
118 |
+
y_values = []
|
119 |
+
|
120 |
+
# Attempt to detect data structure
|
121 |
+
if len(data_parsed) > 0:
|
122 |
+
if isinstance(data_parsed[0], dict) and len(data_parsed[0]) >= 2:
|
123 |
+
# Use first two keys as x and y
|
124 |
+
keys = list(data_parsed[0].keys())
|
125 |
+
x_key, y_key = keys[0], keys[1]
|
126 |
+
|
127 |
+
for item in data_parsed:
|
128 |
+
try:
|
129 |
+
x_values.append(str(item[x_key]))
|
130 |
+
y_values.append(float(item[y_key]))
|
131 |
+
except (KeyError, ValueError, TypeError):
|
132 |
+
continue
|
133 |
+
elif isinstance(data_parsed[0], (list, tuple)) and len(data_parsed[0]) >= 2:
|
134 |
+
# Use first two elements as x and y
|
135 |
+
for item in data_parsed:
|
136 |
+
try:
|
137 |
+
x_values.append(str(item[0]))
|
138 |
+
y_values.append(float(item[1]))
|
139 |
+
except (IndexError, ValueError, TypeError):
|
140 |
+
continue
|
141 |
+
|
142 |
+
if x_values and y_values:
|
143 |
+
# Create a simple bar chart
|
144 |
+
max_y = max(y_values)
|
145 |
+
scale = 20 / max_y if max_y > 0 else 1
|
146 |
+
|
147 |
+
result += f"Chart scale: Each * represents {1/scale:.2f} units\n\n"
|
148 |
+
|
149 |
+
for i, (x, y) in enumerate(zip(x_values, y_values)):
|
150 |
+
bar_length = int(y * scale)
|
151 |
+
result += f"{x.ljust(10)}: {'*' * bar_length} ({y})\n"
|
152 |
+
else:
|
153 |
+
result += "Could not extract plottable values from the data"
|
154 |
else:
|
155 |
+
result += "Data is not in a format suitable for ASCII chart display"
|
156 |
else:
|
157 |
+
return f"Unsupported visualization type: {chart_type}. Use 'summary', 'table', or 'ascii'."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
|
159 |
+
return result
|
|
|
160 |
except Exception as e:
|
161 |
return f"Error creating visualization: {str(e)}"
|
162 |
|