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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more