Spaces:
Sleeping
Sleeping
File size: 12,193 Bytes
d1ae699 86e4e85 d1ae699 81b031b 86e4e85 81b031b dcae7f9 8ec449d dcae7f9 86e4e85 944bc86 dcae7f9 86e4e85 dcae7f9 81b031b dcae7f9 735010b 81b031b dcae7f9 944bc86 dcae7f9 a791ab7 dcae7f9 944bc86 86e4e85 4b10064 86e4e85 dcae7f9 4b10064 86e4e85 4b10064 dcae7f9 86e4e85 dcae7f9 86e4e85 4b10064 86e4e85 4b10064 86e4e85 4b10064 86e4e85 4b10064 86e4e85 4b10064 944bc86 4b10064 d1ae699 81b031b 86e4e85 dcae7f9 8ec449d 4b10064 dcae7f9 8ec449d dcae7f9 4b10064 735010b 86e4e85 944bc86 86e4e85 81b031b 4b10064 86e4e85 735010b 86e4e85 c4a9b3e 86e4e85 dcae7f9 86e4e85 390dba3 86e4e85 4b10064 86e4e85 4b10064 86e4e85 4b10064 86e4e85 a791ab7 86e4e85 4b10064 a791ab7 86e4e85 735010b 86e4e85 735010b 86e4e85 4b10064 86e4e85 4b10064 86e4e85 735010b 86e4e85 735010b 86e4e85 81b031b dcae7f9 86e4e85 735010b dcae7f9 86e4e85 8ec449d 81b031b 86e4e85 a791ab7 d1ae699 81b031b d1ae699 dcae7f9 86e4e85 944bc86 81b031b 86e4e85 76038a5 86e4e85 81b031b a791ab7 86e4e85 81b031b 86e4e85 81b031b 86e4e85 a791ab7 86e4e85 81b031b 86e4e85 dcae7f9 81b031b 86e4e85 5d6ace3 81b031b dcae7f9 86e4e85 dcae7f9 81b031b e45c34b 86e4e85 4b10064 86e4e85 4b10064 86e4e85 735010b 944bc86 8ec449d 86e4e85 8ec449d 86e4e85 8ec449d eebd9e7 dcae7f9 944bc86 81b031b dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 dcae7f9 86e4e85 | 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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | #!/usr/bin/env python3
"""
Plotly + Pyodide - Fixed Data Display Issue
"""
import gradio as gr
def create_pyodide_interface():
"""Create interface with fixed Plotly data handling"""
pyodide_html = '''
<div id="pyodide-container" style="border: 1px solid #ddd; padding: 15px; border-radius: 5px; margin: 10px 0;">
<div id="status" style="font-weight: bold; padding: 10px; background: #f0f0f0; border-radius: 3px;">
π Loading Pyodide + Plotly...
</div>
<div id="output" style="display:none; margin-top: 10px;">
<h4>Results:</h4>
<pre id="text-output" style="background: #f8f8f8; padding: 10px; border-radius: 3px; max-height: 200px; overflow-y: auto; white-space: pre-wrap;"></pre>
<div id="plots" style="margin-top: 15px;"></div>
</div>
</div>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://cdn.jsdelivr.net/pyodide/v0.25.0/full/pyodide.js"></script>
<script>
let pyodide = null;
let ready = false;
let plotId = 0;
function updateStatus(msg, color = 'black') {
const statusEl = document.getElementById('status');
if (statusEl) {
statusEl.innerHTML = msg;
statusEl.style.color = color;
}
console.log('Status:', msg);
}
// Enhanced plot renderer with data debugging
window.renderPlotWithDebug = function(figureJson) {
try {
console.log('Received figure JSON:', figureJson.substring(0, 200) + '...');
plotId++;
const containerId = 'plot-' + plotId;
const plotsDiv = document.getElementById('plots');
if (!plotsDiv) {
console.error('Plots container not found');
return false;
}
// Parse the figure
const figDict = JSON.parse(figureJson);
console.log('Parsed figure keys:', Object.keys(figDict));
console.log('Data array length:', figDict.data ? figDict.data.length : 'No data');
if (figDict.data && figDict.data.length > 0) {
console.log('First trace:', figDict.data[0]);
console.log('First trace x:', figDict.data[0].x);
console.log('First trace y:', figDict.data[0].y);
}
// Create plot container
const plotWrapper = document.createElement('div');
plotWrapper.innerHTML = `
<div style="margin: 15px 0;">
<h5 style="margin: 10px 0;">π Plot ${plotId}</h5>
<div id="${containerId}" style="width: 100%; height: 500px; border: 1px solid #ccc; border-radius: 5px;"></div>
</div>
`;
plotsDiv.appendChild(plotWrapper);
// Enhanced layout with better defaults
const layout = figDict.layout || {};
layout.margin = layout.margin || {l: 50, r: 50, t: 50, b: 50};
layout.autosize = true;
// Create plot with config
const config = {
responsive: true,
displayModeBar: true,
displaylogo: false
};
Plotly.newPlot(containerId, figDict.data, layout, config);
console.log('Plot created successfully with ID:', containerId);
return true;
} catch (error) {
console.error('Plot rendering error:', error);
console.error('Error details:', error.message);
return false;
}
};
async function initPyodide() {
try {
updateStatus('π Loading Pyodide...', 'blue');
pyodide = await loadPyodide();
updateStatus('π¦ Installing packages...', 'blue');
await pyodide.loadPackage(['numpy', 'pandas', 'micropip']);
updateStatus('π Installing Plotly...', 'blue');
await pyodide.runPythonAsync(`
import micropip
await micropip.install('plotly')
`);
updateStatus('π§ Setting up integration...', 'blue');
// Python setup with enhanced debugging
pyodide.runPython(`
import json
from js import renderPlotWithDebug
def show_plot_debug(fig):
try:
print("=== PLOT DEBUG INFO ===")
# Convert to dict and inspect
fig_dict = fig.to_dict()
print(f"Figure has {len(fig_dict.get('data', []))} traces")
# Debug each trace
for i, trace in enumerate(fig_dict.get('data', [])):
print(f"Trace {i}: type={trace.get('type', 'unknown')}")
print(f" x data: {trace.get('x', 'missing')}")
print(f" y data: {trace.get('y', 'missing')}")
print(f" mode: {trace.get('mode', 'default')}")
# Convert to JSON for JavaScript
fig_json = json.dumps(fig_dict)
print(f"JSON length: {len(fig_json)} characters")
# Send to JavaScript
success = renderPlotWithDebug(fig_json)
if success:
print("β
Plot rendered successfully!")
else:
print("β Plot rendering failed")
print("=== END DEBUG INFO ===")
return success
except Exception as e:
print(f"β Plot error: {e}")
import traceback
traceback.print_exc()
return False
# Setup Plotly with debugging
try:
import plotly.graph_objects as go
import plotly.express as px
import numpy as np
# Test data creation
print("Testing data creation...")
test_x = [1, 2, 3, 4, 5]
test_y = [1, 4, 9, 16, 25]
print(f"Test data - x: {test_x}, y: {test_y}")
# Patch show method
original_show = go.Figure.show
go.Figure.show = lambda self, *args, **kwargs: show_plot_debug(self)
print("β
Plotly setup complete with debugging!")
except Exception as e:
print(f"β Plotly setup failed: {e}")
import traceback
traceback.print_exc()
print("π Environment ready for testing!")
`);
ready = true;
updateStatus('β
Ready with debug mode!', 'green');
document.getElementById('output').style.display = 'block';
document.getElementById('text-output').textContent = 'System ready! The debug info will help identify data issues.';
} catch (error) {
console.error('Init error:', error);
updateStatus('β Failed: ' + error.message, 'red');
}
}
async function executeUserCode(code) {
if (!ready) {
return 'Not ready. Wait for green status.';
}
try {
updateStatus('βΆοΈ Executing with debug...', 'blue');
// Clear previous plots
document.getElementById('plots').innerHTML = '';
// Capture output
pyodide.runPython(`
import sys
from io import StringIO
old_stdout = sys.stdout
sys.stdout = capture = StringIO()
`);
// Execute code
let result = pyodide.runPython(code);
// Get output
let output = pyodide.runPython(`
sys.stdout = old_stdout
capture.getvalue()
`);
// Display
document.getElementById('text-output').textContent = output || 'Executed successfully';
updateStatus('β
Complete!', 'green');
return output || 'Success';
} catch (error) {
const errorMsg = 'Error: ' + error.toString();
document.getElementById('text-output').textContent = errorMsg;
updateStatus('β Error', 'red');
return errorMsg;
}
}
// Wait for CDNs and init
function waitForCDNs() {
if (typeof loadPyodide !== 'undefined' && typeof Plotly !== 'undefined') {
console.log('CDNs loaded, initializing...');
initPyodide();
} else {
setTimeout(waitForCDNs, 1000);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', waitForCDNs);
} else {
waitForCDNs();
}
window.executeUserCode = executeUserCode;
window.checkReady = () => ready;
</script>
'''
return pyodide_html
# Gradio interface
with gr.Blocks() as demo:
gr.Markdown("# π Plotly Debug Version")
gr.Markdown("**Diagnose why data points aren't showing**")
pyodide_interface = gr.HTML(create_pyodide_interface())
with gr.Row():
with gr.Column():
code_input = gr.Textbox(
value="""# Debug Test - Simple Data
import plotly.graph_objects as go
import numpy as np
print("Creating simple test plot...")
# Explicit simple data
x_data = [1, 2, 3, 4, 5]
y_data = [2, 4, 6, 8, 10]
print(f"X data: {x_data}")
print(f"Y data: {y_data}")
# Create figure step by step
fig = go.Figure()
# Add trace with explicit parameters
fig.add_trace(go.Scatter(
x=x_data,
y=y_data,
mode='markers+lines',
name='Test Data',
marker=dict(
size=12,
color='red',
symbol='circle'
),
line=dict(
color='blue',
width=3
)
))
# Explicit layout
fig.update_layout(
title='Debug Test Plot',
xaxis=dict(title='X Values', range=[0, 6]),
yaxis=dict(title='Y Values', range=[0, 12]),
width=700,
height=500,
showlegend=True
)
print("Calling fig.show()...")
fig.show()""",
lines=20,
label="Debug Test Code"
)
execute_btn = gr.Button("π Execute Debug", variant="primary")
with gr.Column():
status_display = gr.Textbox(
label="Status",
interactive=False,
lines=4
)
check_btn = gr.Button("π Check")
# Simple test examples
gr.Markdown("""
### π§ͺ Progressive Tests:
**Test 1 - Minimal:**
```python
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(x=[1,2,3], y=[1,2,3]))
fig.show()
```
**Test 2 - With NumPy:**
```python
import plotly.graph_objects as go
import numpy as np
x = np.array([1,2,3,4,5])
y = np.array([1,4,9,16,25])
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='markers'))
fig.show()
```
**Test 3 - Express:**
```python
import plotly.express as px
import pandas as pd
df = pd.DataFrame({'x': [1,2,3], 'y': [1,4,9]})
fig = px.scatter(df, x='x', y='y')
fig.show()
```
""")
execute_btn.click(
fn=None,
inputs=[code_input],
outputs=[status_display],
js="(code) => window.executeUserCode ? window.executeUserCode(code) : 'Not ready'"
)
check_btn.click(
fn=None,
inputs=[],
outputs=[status_display],
js="() => window.checkReady ? (window.checkReady() ? 'β
Ready' : 'β³ Loading') : 'β Error'"
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860, share=False) |