Commit
·
a4d09ea
1
Parent(s):
e7eb58c
mv1
Browse files
app.py
CHANGED
|
@@ -64,6 +64,19 @@ def generate_chart(data: Union[Dict, List[Dict], pd.DataFrame],
|
|
| 64 |
A Plotly Figure object (interactive) or None on error
|
| 65 |
"""
|
| 66 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
# Convert data to DataFrame if it's a list of dicts
|
| 68 |
if isinstance(data, list):
|
| 69 |
df = pd.DataFrame(data)
|
|
@@ -77,17 +90,50 @@ def generate_chart(data: Union[Dict, List[Dict], pd.DataFrame],
|
|
| 77 |
|
| 78 |
# Generate the appropriate chart type
|
| 79 |
fig = None
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
return None
|
| 92 |
|
| 93 |
# Update layout
|
|
|
|
| 64 |
A Plotly Figure object (interactive) or None on error
|
| 65 |
"""
|
| 66 |
try:
|
| 67 |
+
# Debug: Log the input data
|
| 68 |
+
logger.info(f"Generating {chart_type} chart with x={x}, y={y}")
|
| 69 |
+
logger.info(f"Input data type: {type(data)}")
|
| 70 |
+
if hasattr(data, 'head'): # It's a DataFrame
|
| 71 |
+
logger.info(f"DataFrame columns: {data.columns.tolist()}")
|
| 72 |
+
logger.info(f"Data sample:\n{data.head(2).to_string()}")
|
| 73 |
+
elif isinstance(data, (list, dict)):
|
| 74 |
+
logger.info(f"Data sample: {str(data)[:500]}...")
|
| 75 |
+
|
| 76 |
+
# Validate data
|
| 77 |
+
if data is None or (hasattr(data, 'empty') and data.empty) or (isinstance(data, (list, dict)) and not data):
|
| 78 |
+
logger.error("No data provided to generate_chart")
|
| 79 |
+
return None
|
| 80 |
# Convert data to DataFrame if it's a list of dicts
|
| 81 |
if isinstance(data, list):
|
| 82 |
df = pd.DataFrame(data)
|
|
|
|
| 90 |
|
| 91 |
# Generate the appropriate chart type
|
| 92 |
fig = None
|
| 93 |
+
try:
|
| 94 |
+
if chart_type == 'bar':
|
| 95 |
+
fig = px.bar(df, x=x, y=y, title=title)
|
| 96 |
+
elif chart_type == 'line':
|
| 97 |
+
fig = px.line(df, x=x, y=y, title=title)
|
| 98 |
+
elif chart_type == 'pie':
|
| 99 |
+
fig = px.pie(df, names=x, values=y, title=title, hole=0)
|
| 100 |
+
elif chart_type == 'scatter':
|
| 101 |
+
# Ensure we have valid numeric data for scatter plot
|
| 102 |
+
if df[x].isnull().any() or df[y].isnull().any():
|
| 103 |
+
logger.error(f"Null values found in data for scatter plot. x: {df[x].isnull().sum()}, y: {df[y].isnull().sum()}")
|
| 104 |
+
# Try to convert to numeric, coercing errors
|
| 105 |
+
df[x] = pd.to_numeric(df[x], errors='coerce')
|
| 106 |
+
df[y] = pd.to_numeric(df[y], errors='coerce')
|
| 107 |
+
# Drop rows with NaN values
|
| 108 |
+
df = df.dropna(subset=[x, y])
|
| 109 |
+
if df.empty:
|
| 110 |
+
logger.error("No valid numeric data points after cleaning")
|
| 111 |
+
return None
|
| 112 |
+
logger.info("Data cleaned for scatter plot")
|
| 113 |
+
fig = px.scatter(df, x=x, y=y, title=title)
|
| 114 |
+
elif chart_type == 'histogram':
|
| 115 |
+
fig = px.histogram(df, x=x, title=title)
|
| 116 |
+
else:
|
| 117 |
+
logger.error(f"Unsupported chart type: {chart_type}")
|
| 118 |
+
return None
|
| 119 |
+
|
| 120 |
+
if fig is None:
|
| 121 |
+
logger.error("Failed to generate figure")
|
| 122 |
+
return None
|
| 123 |
+
|
| 124 |
+
except Exception as e:
|
| 125 |
+
logger.error(f"Error generating {chart_type} chart: {str(e)}", exc_info=True)
|
| 126 |
+
# Try to provide a more helpful error message
|
| 127 |
+
if 'NoneType' in str(e) and 'heuristic' in str(e):
|
| 128 |
+
logger.error("A* search heuristic failed - likely due to invalid or missing coordinate data")
|
| 129 |
+
# Try to identify which column has the issue
|
| 130 |
+
for col in [x, y]:
|
| 131 |
+
if col and col in df.columns:
|
| 132 |
+
null_count = df[col].isnull().sum()
|
| 133 |
+
if null_count > 0:
|
| 134 |
+
logger.error(f"Column '{col}' has {null_count} null values")
|
| 135 |
+
if not pd.api.types.is_numeric_dtype(df[col]):
|
| 136 |
+
logger.error(f"Column '{col}' is not numeric. Type: {df[col].dtype}")
|
| 137 |
return None
|
| 138 |
|
| 139 |
# Update layout
|