Public
Edited
Feb 15, 2023
Importers
Insert cell
Insert cell
import {py as py0, pyodide} from "@gnestor/pyodide"
Insert cell
Insert cell
Insert cell
pd=py`import pandas as pd
pd`
Insert cell
df=pd.DataFrame([1,2,3,4])
Insert cell
df.head().toString()
Insert cell
py`str(${df}.iloc[1,0])`
Insert cell
{
let f=df.copy()
f=f+1
return f
}
Insert cell
Insert cell
class Py {
//function way will not save context,
//if codes has many variables
//you can't access them next time.
//make it a class, global will save context,
//but observable is reactive,
//so one cell changes,others follow.
//think it like REPL.
//drawback:more data transfer.
constructor() {
this.globals = {}
}

async py(strings, ...expressions) {
//`` save strings into two parts,strings[arr],and expressions (${})
const lastLine=strings.raw[strings.raw.length-1].trim().split("\n")
let outputVar=lastLine.slice(-1)
let code = strings.reduce((result, string, index) => {
if (expressions[index]) {
const name = `x${index}`;
this.globals.set(name,expressions[index])
return result + string + name;
}else{
return result+string
}
}, '');

//make the exec result to be [] like,
//append [outputVar,global()] at the end of code,
code+=`\n[${outputVar},globals()]`
await pyodide.loadPackagesFromImports(code);
const result = await pyodide.pyodide_py.eval_code_async(
code,
pyodide.toPy(this.globals)
);
const jsResult = result.toJs()
this.globals = jsResult[1]
return jsResult[0]
}
}
Insert cell
f=P.py`s=[1,2,4]
s
`
Insert cell
f1=P.py`d1=[n+1 for n in ${f}]
d1`
Insert cell
Insert cell
P=new Py()
Insert cell
P.py`import pandas as pd
pd`
Insert cell
P.py`pd.__version__`
Insert cell
s=P.py`
s=pd.DataFrame([1,2,3],columns=['y'])
s`
Insert cell
Insert cell
Inputs.table(s.to_dict('record').toJs().map(Object.fromEntries))
Insert cell
P.py`str(s.iloc[0,0])`
Insert cell
s.add(1).toString()
Insert cell
s.to_dict('records')
.toJs()
.map(Object.fromEntries)
Insert cell
g=P.py`s.copy()+1`
Insert cell
h=P.py`h=${g}+5
h`
Insert cell
g.toString()
Insert cell
Insert cell
//class version
plt=P.py`
import matplotlib.pyplot as plt
import pandas as pd
import io
import base64
import types
from js import document

df=pd.DataFrame({'y':[4,5,2,8]},index=[1,2,3,4])
def show(self):
buf = io.BytesIO()
self.savefig(buf, format='png')
buf.seek(0)
img_str = 'data:image/png;base64,' + base64.b64encode(buf.read()).decode('UTF-8')
el = document.createElement('img')
el.src = img_str
return el

plt._show = types.MethodType(plt.show, plt)
plt.show = types.MethodType(show, plt)
s=df.plot()
# or show(plt)
plt.show()
`
Insert cell
//function version
//see:https://observablehq.com/@gnestor/pyodide-demo
{
let plt =await py`
from matplotlib import pyplot as plt
import types
import io
import base64
from js import document
def show(self):
buf = io.BytesIO()
self.savefig(buf, format='png')
buf.seek(0)
img_str = 'data:image/png;base64,' + base64.b64encode(buf.read()).decode('UTF-8')
el = document.createElement('img')
el.src = img_str
return el
plt._show = types.MethodType(plt.show, plt)
plt.show = types.MethodType(show, plt)
plt`
plt.figure();
plt.plot(pyodide.toPy([1,2,3]),pyodide.toPy([1,2,3]));
return plt.show();
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more