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

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