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 |
|