mic3333 commited on
Commit
5d6ace3
Β·
verified Β·
1 Parent(s): 76038a5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -41
app.py CHANGED
@@ -45,10 +45,10 @@ def create_pyodide_interface():
45
  indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/"
46
  });
47
 
48
- updateStatus('πŸ“¦ Loading Python packages (numpy, matplotlib, pandas)...', 'blue');
49
 
50
- await pyodide.loadPackage(["numpy", "matplotlib", "pandas"]);
51
- updateStatus('βš™οΈ Setting up matplotlib backend...', 'blue');
52
 
53
  // Set up matplotlib backend for web - IMPROVED VERSION
54
  pyodide.runPython(`
@@ -57,13 +57,18 @@ def create_pyodide_interface():
57
  import matplotlib.pyplot as plt
58
  import numpy as np
59
  import pandas as pd
 
 
 
60
  import io
61
  import base64
 
62
 
63
- # Global variable to store plot data
64
  _current_plot_data = None
 
65
 
66
- def capture_plot():
67
  global _current_plot_data
68
  try:
69
  if len(plt.get_fignums()) > 0:
@@ -73,30 +78,46 @@ def create_pyodide_interface():
73
  plot_data = buffer.getvalue()
74
  buffer.close()
75
  _current_plot_data = base64.b64encode(plot_data).decode()
76
- plt.close('all') # Close all figures
77
  return _current_plot_data
78
- else:
79
- _current_plot_data = None
80
- return None
81
  except Exception as e:
82
- print(f"Plot capture error: {e}")
83
- _current_plot_data = None
84
  return None
85
 
86
- def get_plot_data():
87
- return _current_plot_data
88
-
89
- def clear_plot_data():
90
- global _current_plot_data
91
- _current_plot_data = None
 
 
92
 
93
- # Override plt.show() to capture plots automatically
94
  original_show = plt.show
95
  def custom_show(*args, **kwargs):
96
- return capture_plot()
97
  plt.show = custom_show
98
 
99
- print("Pyodide Python environment ready!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  `);
101
 
102
  pyodideReady = true;
@@ -147,12 +168,15 @@ def create_pyodide_interface():
147
  captured_output.getvalue()
148
  `);
149
 
150
- // Get plot data separately
151
- let plotData = pyodide.runPython('get_plot_data()');
 
152
 
153
  console.log('Stdout length:', stdout ? stdout.length : 0);
154
- console.log('Plot data length:', plotData ? plotData.length : 0);
155
- console.log('Plot data preview:', plotData ? plotData.substring(0, 50) + '...' : 'None');
 
 
156
 
157
  // Display results
158
  let outputDiv = document.getElementById('pyodide-output');
@@ -161,36 +185,49 @@ def create_pyodide_interface():
161
 
162
  outputDiv.style.display = 'block';
163
 
164
- // Display clean text output
165
  let textOutput = stdout || (result !== undefined ? String(result) : '');
166
  outputText.textContent = textOutput || 'Code executed successfully (no output)';
167
 
168
- // Display plot if generated
169
- if (plotData && plotData.length > 100) {
170
- console.log('Displaying plot...');
171
- plotContainer.innerHTML = `
 
172
  <div style="margin: 10px 0;">
173
- <h5>πŸ“Š Generated Plot:</h5>
174
- <img src="data:image/png;base64,${plotData}"
175
- style="max-width: 100%; height: auto; border: 1px solid #ddd; border-radius: 3px;"
176
- alt="Generated Plot">
177
  </div>
178
  `;
179
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  if (textOutput.trim()) {
181
- outputText.textContent += '\\n\\nπŸ“Š Plot generated and displayed below!';
182
  } else {
183
- outputText.textContent = 'πŸ“Š Plot generated and displayed below!';
184
  }
185
- updateStatus('βœ… Code executed with plot generated!', 'green');
186
- return 'Code executed successfully with plot';
187
  } else {
188
- console.log('No plot data detected');
189
- plotContainer.innerHTML = '';
190
  updateStatus('βœ… Code executed successfully!', 'green');
191
- return textOutput || 'Code executed successfully';
192
  }
193
 
 
 
194
  } catch (error) {
195
  console.error('Execution error:', error);
196
  document.getElementById('output-text').textContent = 'Error: ' + error.toString();
 
45
  indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/"
46
  });
47
 
48
+ updateStatus('πŸ“¦ Loading Python packages (numpy, matplotlib, pandas, plotly)...', 'blue');
49
 
50
+ await pyodide.loadPackage(["numpy", "matplotlib", "pandas", "plotly"]);
51
+ updateStatus('πŸ“¦ All packages loaded, setting up backends...', 'blue');
52
 
53
  // Set up matplotlib backend for web - IMPROVED VERSION
54
  pyodide.runPython(`
 
57
  import matplotlib.pyplot as plt
58
  import numpy as np
59
  import pandas as pd
60
+ import plotly.graph_objects as go
61
+ import plotly.express as px
62
+ import plotly
63
  import io
64
  import base64
65
+ import json
66
 
67
+ # Global variables for plot data
68
  _current_plot_data = None
69
+ _current_plotly_data = None
70
 
71
+ def capture_matplotlib():
72
  global _current_plot_data
73
  try:
74
  if len(plt.get_fignums()) > 0:
 
78
  plot_data = buffer.getvalue()
79
  buffer.close()
80
  _current_plot_data = base64.b64encode(plot_data).decode()
81
+ plt.close('all')
82
  return _current_plot_data
83
+ return None
 
 
84
  except Exception as e:
85
+ print(f"Matplotlib capture error: {e}")
 
86
  return None
87
 
88
+ def capture_plotly(fig):
89
+ global _current_plotly_data
90
+ try:
91
+ _current_plotly_data = fig.to_html(include_plotlyjs='cdn', div_id='plotly-div')
92
+ return _current_plotly_data
93
+ except Exception as e:
94
+ print(f"Plotly capture error: {e}")
95
+ return None
96
 
97
+ # Override functions
98
  original_show = plt.show
99
  def custom_show(*args, **kwargs):
100
+ return capture_matplotlib()
101
  plt.show = custom_show
102
 
103
+ # Override plotly show
104
+ original_plotly_show = go.Figure.show
105
+ def custom_plotly_show(self, *args, **kwargs):
106
+ return capture_plotly(self)
107
+ go.Figure.show = custom_plotly_show
108
+
109
+ def get_matplotlib_data():
110
+ return _current_plot_data
111
+
112
+ def get_plotly_data():
113
+ return _current_plotly_data
114
+
115
+ def clear_plot_data():
116
+ global _current_plot_data, _current_plotly_data
117
+ _current_plot_data = None
118
+ _current_plotly_data = None
119
+
120
+ print("Pyodide ready with matplotlib AND plotly support!")
121
  `);
122
 
123
  pyodideReady = true;
 
168
  captured_output.getvalue()
169
  `);
170
 
171
+ // Get both types of plot data
172
+ let matplotlibData = pyodide.runPython('get_matplotlib_data()');
173
+ let plotlyData = pyodide.runPython('get_plotly_data()');
174
 
175
  console.log('Stdout length:', stdout ? stdout.length : 0);
176
+ console.log('Matplotlib data length:', matplotlibData ? matplotlibData.length : 0);
177
+ console.log('Plotly data length:', plotlyData ? plotlyData.length : 0);
178
+ console.log('Matplotlib data preview:', matplotlibData ? matplotlibData.substring(0, 50) + '...' : 'None');
179
+ console.log('Plotly data preview:', plotlyData ? plotlyData.substring(0, 50) + '...' : 'None');
180
 
181
  // Display results
182
  let outputDiv = document.getElementById('pyodide-output');
 
185
 
186
  outputDiv.style.display = 'block';
187
 
 
188
  let textOutput = stdout || (result !== undefined ? String(result) : '');
189
  outputText.textContent = textOutput || 'Code executed successfully (no output)';
190
 
191
+ // Display plots
192
+ let plotHtml = '';
193
+
194
+ if (matplotlibData && matplotlibData.length > 100) {
195
+ plotHtml += `
196
  <div style="margin: 10px 0;">
197
+ <h5>πŸ“Š Matplotlib Plot:</h5>
198
+ <img src="data:image/png;base64,${matplotlibData}"
199
+ style="max-width: 100%; height: auto; border: 1px solid #ddd;"
200
+ alt="Matplotlib Plot">
201
  </div>
202
  `;
203
+ }
204
+
205
+ if (plotlyData) {
206
+ plotHtml += `
207
+ <div style="margin: 10px 0;">
208
+ <h5>πŸ“Š Interactive Plotly Plot:</h5>
209
+ <div style="border: 1px solid #ddd; border-radius: 3px;">
210
+ ${plotlyData}
211
+ </div>
212
+ </div>
213
+ `;
214
+ }
215
+
216
+ plotContainer.innerHTML = plotHtml;
217
+
218
+ if (plotHtml) {
219
  if (textOutput.trim()) {
220
+ outputText.textContent += '\\n\\nπŸ“Š Plot(s) generated and displayed below!';
221
  } else {
222
+ outputText.textContent = 'πŸ“Š Plot(s) generated and displayed below!';
223
  }
224
+ updateStatus('βœ… Code executed with plot(s) generated!', 'green');
 
225
  } else {
 
 
226
  updateStatus('βœ… Code executed successfully!', 'green');
 
227
  }
228
 
229
+ return textOutput || 'Code executed successfully';
230
+
231
  } catch (error) {
232
  console.error('Execution error:', error);
233
  document.getElementById('output-text').textContent = 'Error: ' + error.toString();