Public
Edited
Mar 12, 2023
Importers
6 stars
Insert cell
Insert cell
plot(x => Math.pow(x, 3))
Insert cell
Insert cell
plot((x, s) => s.noise(x * 2 + 10) * 2 - 1)
Insert cell
Insert cell
plot(x => x % 0.5, {
w: width,
h: 200,
minX: -Math.PI * 2,
maxX: Math.PI * 2,
play: false
})
Insert cell
Insert cell
plot((x, s) => {
if(s.frameCount % 2) {
s.stroke('red')
return s.sin(x * s.TAU)
}
else {
s.stroke('lime')
return s.cos(x * s.TAU)
}
})
Insert cell
Insert cell
plot = (f = (x) => Math.sin(x), options = {}) => {
let {
w = 400, // width of the plot
h = 400, // height of the plot
minX = -1, // minimum value on X axis
maxX = 1, // maximum value on X axis
minY = -1, // minimum value on Y axis
maxY = 1, // maximum value on Y axis
zoom = undefined, // shortcut to set minX = minY = -zoom & maxX = maxY = zoom
play = true, // is the plot animated
speed = 2 // animation speed
} = options

if(zoom) {
minX = minY = zoom[0]
maxX = maxY = zoom[1]
}

return p5(s => {
let mX, mY
s.setup = () => {
const canvas = s.createCanvas(w, h)
s.cursor(s.HAND)
mX = 0
mY = f(mX, s)
canvas.elt.addEventListener('click', e => {
play = !play
if(play) s.loop()
})
}

s.draw = () => {
let t = play ? (s.frameCount * speed / w) % 1.2 : 1.01

s.background(0)

s.noFill()
s.stroke(80)
s.strokeWeight(2)

const x0 = s.map(0, minX, maxX, 0, w)
s.line(x0, 0, x0, h)
const y0 = s.map(0, minY, maxY, h, 0)
s.line(0, y0, w, y0)

s.stroke(255, 0, 0)
s.strokeWeight(1)

let x = 0
let y = 0
s.beginShape()
for(x = 0; x < w * t; x ++) {
const X = s.map(x, 0, w, minX, maxX)
const Y = f(X, s)
y = s.map(Y, minY, maxY, h, 0)
s.vertex(x, y)
}
s.endShape()

s.noStroke()
s.fill('red')
s.circle(x, y, 5)

s.fill(255)
s.circle(s.map(mX, minX, maxX, 0, w), s.map(mY, minY, maxY, h, 0), 5)

s.noStroke()
s.fill(255)
s.textAlign(s.LEFT)
s.text(`X: [ ${(minX * 1000 | 0) / 1000}, ${(maxX * 1000 | 0) / 1000} ]`, 5, 15)
s.text(`Y: [ ${(minY * 1000 | 0) / 1000}, ${(maxY * 1000 | 0) / 1000} ]`, 5, 30)
s.textAlign(s.RIGHT)
s.text(`X: ${(mX * 1000 | 0) / 1000}`, s.width - 5, 15)
s.text(`Y: ${(mY * 1000 | 0) / 1000}`, s.width - 5, 30)

if(!play) s.noLoop()
}

s.mouseMoved = () => {
if(s.mouseX >= 0 && s.mouseX <= s.width && s.mouseY >= 0 && s.mouseY <= s.height) {
s.mouseX = s.constrain(s.mouseX, 0, w)
mX = s.map(s.mouseX, 0, w, minX, maxX)
mY = f(mX, s)
s.loop()
}
}
})
}
Insert cell
Insert cell
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