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)