Public
Edited
Dec 30, 2022
2 forks
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
height: 400,
width,
axis: null,
x: {
axis: "top"
},
y: {
axis: null,
domain: [0, 20]
},
fy: {
axis: "right",
label: null,
domain: domains.day,
padding: 0.05
},
facet: {
data: data,
y: "day",
marginRight: 140
},
marks: [
Plot.areaY(
data,
Plot.binX(
{ y: "count" },
{
x: "time",
fillOpacity: 0.2,
thresholds: d3.timeMinute.every(15),
curve: "basis"
}
)
),
Plot.lineY(
data,
Plot.binX(
{ y: "count" },
{
x: "time",
strokeWidth: 1,
thresholds: d3.timeMinute.every(15),
curve: "basis"
}
)
)
]
})
Insert cell
Plot.plot({
width,
y: { domain: domains.day, label: "" },
x: { ticks: 3 },
facet: { data: data, x: "month" },
fx: { domain: domains.month.slice(7), label: "" },
marginLeft: 100,
marks: [
Plot.frame(),
Plot.tickX(data, {
x: "time",
y: "day",
strokeOpacity: 0.1
})
]
})
Insert cell
Plot.plot({
width,
y: { domain: domains.month.slice(7), label: "" },
x: { ticks: 1 },
facet: { data: data, x: "weekend" },
fx: { label: "" },
marginLeft: 100,
marks: [
Plot.frame(),
Plot.tickX(data, {
x: "time",
y: "month",
strokeOpacity: 0.1
})
]
})
Insert cell
Plot.plot({
width,
padding: 0,
marks: [
Plot.frame(),
Plot.tickX(
data,
Plot.binX(
{ strokeOpacity: "count" },
{
x: "time",
thresholds: d3.timeMinute
}
)
)
]
})
Insert cell
Plot.plot({
width,
padding: 0,
x: { label: "" },
marks: [
Plot.frame(),
Plot.tickX(
data,
Plot.binX(
{ strokeOpacity: "count" },
{
x: "playedAt",
thresholds: d3.timeMinute
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { ticks: 2, line: true },
facet: { data: data, x: "day" },
fx: { domain: domains.day, label: "", line: true },
padding: 0,
marks: [
Plot.frame(),
Plot.tickX(data, {
x: "time",
strokeOpacity: 0.1
})
]
})
Insert cell
Insert cell
Insert cell
Plot.plot({
width,
padding: 0,
marks: [
Plot.frame(),
Plot.tickX(
artistData,
Plot.binX(
{ strokeOpacity: "count" },
{
x: "time",
thresholds: d3.timeMinute
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { ticks: 2, line: true },
facet: { data: artistData, x: "day" },
fx: { domain: domains.day, label: "", line: true },
padding: 0,
marks: [
Plot.frame(),
Plot.tickX(
artistData,
Plot.binX(
{ strokeOpacity: "count" },
{
x: "time",
thresholds: d3.timeMinute
// stroke: "timeOfDay"
}
)
)
]
})
Insert cell
Plot.plot({
width,
padding: 0,
marks: [
Plot.frame(),
Plot.tickX(
artistData,
Plot.binX(
{ strokeOpacity: "count" },
{
x: "playedAt",
thresholds: d3.timeMinute
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { label: "" },
// r: { range: [1, 10] },
marks: [
Plot.dot(
artistData,
Plot.binX(
{ r: "count" },
{
x: "time",
thresholds: d3.timeMinute.every(5),
stroke: "purple",
strokeOpacity: 0.3
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { ticks: 2 },
facet: { data: artistData, x: "day" },
fx: { domain: domains.day, label: "" },
padding: 0,
marks: [
Plot.dot(
artistData,
Plot.binX(
{ r: "count" },
{
x: "time",
thresholds: d3.timeMinute.every(30),
stroke: "purple",
strokeOpacity: 0.3
// stroke: "timeOfDay"
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { label: "" },
marks: [
Plot.dot(
artistData,
Plot.binX(
{ r: "count" },
{
x: "playedAt",
thresholds: d3.timeHour,
stroke: "purple",
strokeOpacity: 0.3
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { label: "" },
marks: [
Plot.dot(
artistData,
Plot.bin(
{ r: "count" },
{
x: "playedAt",
y: "time",
thresholds: d3.timeMinute.every(15),
stroke: "purple",
strokeOpacity: 0.5
}
)
)
]
})
Insert cell
Plot.plot({
facet: { data: artistData, y: "timeOfDay", marginLeft: 100 },
fy: { domain: domains.timeOfDay, label: "" },
x: { label: "" },
marks: [
Plot.dot(
artistData,
Plot.binX(
{ r: "count" },
{
x: "playedAt",
thresholds: d3.timeHour,
strokeOpacity: 0.4,
stroke: "purple"
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { label: "", ticks: 3 },
facet: { data: artistData, x: "month" },
fx: { label: "", domain: domains.month.slice(7) },
padding: 0,
marks: [
Plot.dot(
artistData,
Plot.binY(
{ r: "count" },
{
y: "time",
x: "dayOfMonth",
thresholds: d3.timeMinute.every(30),
stroke: "purple",
strokeOpacity: 0.5
}
)
)
]
})
Insert cell
Plot.plot({
width,
y: { domain: domains.day, label: "" },
x: { ticks: 2, round: true },
facet: { data: data, x: "month" },
fx: { domain: domains.month.slice(7), label: "" },
marginLeft: 100,
marks: [
Plot.frame(),
Plot.dotX(
data,
Plot.binX(
{ r: "count" },
{
x: "time",
y: "day",
strokeOpacity: 0.4,
thresholds: d3.timeMinute.every(20)
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { label: "", inset: 20 },
y: { ticks: false },
marginLeft: 120,
marks: [
Plot.dot(
artistData.filter((d) => d.track.album.album_type == "album"),
Plot.binX(
{ r: "count" },
{
x: "time",
y: (d) => d.track.album.name,
thresholds: d3.timeMinute.every(10),
stroke: "purple",
strokeOpacity: 0.5,
sort: { y: "r", reverse: true, limit: 10 }
}
)
),
Plot.image(artistData, {
x: 1,
y: (d) => d.track.album.name,
src: (d) => d.track.album.images[0].url,
dx: -20
})
]
})
Insert cell
Plot.plot({
width,
x: { label: "", ticks: 3, inset: 20 },
marginLeft: 125,
marks: [
Plot.dot(
artistData,
Plot.binX(
{ r: "count" },
{
x: "time",
y: (d) => d.track.name,
thresholds: d3.timeMinute.every(10),
stroke: "purple",
strokeOpacity: 0.5,
sort: { y: "r", reverse: true, limit: 10 }
}
)
),
Plot.image(artistData, {
x: 1,
y: (d) => d.track.name,
src: (d) => d.track.album.images[0].url,
dx: -20
})
]
})
Insert cell
Plot.plot({
width,
x: { label: "", ticks: 3, inset: 20 },
marginLeft: 125,
marks: [
Plot.dot(
artistData,
Plot.binX(
{ r: "count" },
{
x: "playedAt",
y: (d) => d.track.album.name,
thresholds: d3.timeDay,
stroke: "purple",
strokeOpacity: 0.5,
sort: { y: "r", reverse: true, limit: 10 }
}
)
),
Plot.ruleX(monthRules, { strokeOpacity: 0.4 }),
Plot.image(artistData, {
x: d3.min(artistData.map((d) => d.date)),
y: (d) => d.track.album.name,
src: (d) => d.track.album.images[0].url,
dx: -20
})
]
})
Insert cell
Plot.plot({
width,
x: { label: "", ticks: 3, inset: 20 },
marginLeft: 125,
marks: [
Plot.dot(
artistData,
Plot.binX(
{ r: "count" },
{
x: "playedAt",
y: (d) => d.track.name,
z: (d) => d.track.album.name,
thresholds: d3.timeDay,
stroke: "purple",
strokeOpacity: 0.5,
sort: { y: "r", reverse: true, limit: 10 }
}
)
),
Plot.ruleX(monthRules, {
strokeOpacity: 0.4
}),
Plot.image(artistData, {
x: d3.min(artistData.map((d) => d.date)),
y: (d) => d.track.name,
src: (d) => d.track.album.images[0].url,
dx: -20
})
]
})
Insert cell
Insert cell
Plot.plot({
width,
marginLeft: 100,
y: { domain: top5 },
padding: 0,
marks: [
Plot.frame(),
Plot.tickX(
top5Data,
Plot.binX(
{ strokeOpacity: "count" },
{
x: "time",
y: (d) => d.track.artists[0].name,
thresholds: d3.timeMinute
}
)
)
]
})
Insert cell
Plot.plot({
width,
x: { ticks: 2, line: true },
facet: { data: top5Data, x: "day" },
fx: { domain: domains.day, label: "", line: true },
y: { domain: top5 },
marginLeft: 100,
padding: 0,
marks: [
Plot.frame(),
Plot.tickX(
top5Data,
Plot.binX(
{ strokeOpacity: "count" },
{
x: "time",
y: (d) => d.track.artists[0].name,
thresholds: d3.timeMinute
// stroke: "timeOfDay"
}
)
)
]
})
Insert cell
Plot.plot({
width,
padding: 0,
y: { domain: top5 },
marginLeft: 100,
marks: [
Plot.frame(),
Plot.tickX(
top5Data,
Plot.binX(
{ strokeOpacity: "count" },
{
x: "playedAt",
y: (d) => d.track.artists[0].name,
thresholds: d3.timeMinute
}
)
)
]
})
Insert cell
Plot.plot({
width,
y: { domain: domains.day, label: "" },
x: { ticks: 3, round: true },
facet: {
data: top5Data,
x: "month",
y: (d) => d.track.artists[0].name,
marginRight: 100,
marginLeft: 100
},
fy: { domain: top5, marginRight: 100 },
fx: { domain: domains.month.slice(7), label: "" },
marks: [
Plot.frame(),
Plot.dotX(
top5Data,
Plot.binX(
{ r: "count" },
{
x: "time",
y: "day",
strokeOpacity: 0.4,
thresholds: d3.timeMinute.every(20)
}
)
)
]
})
Insert cell
allSongsChart = Plot.plot({
width,
x: { label: "", ticks: 3, inset: 20, axis: "top" },
marginLeft: 175,
marks: [
Plot.dot(
top5Data,
Plot.binX(
{ r: "count" },
{
x: "playedAt",
y: (d) => d.track.name,
thresholds: d3.timeDay,
stroke: "purple",
strokeOpacity: 0.5,
sort: { y: "r", reverse: true, limit: 50 }
}
)
),
Plot.ruleX(monthRules, {
strokeOpacity: 0.4
}),
Plot.image(top5Data, {
x: d3.min(top5Data.map((d) => d.date)),
y: (d) => d.track.name,
src: (d) => d.track.album.images[0].url,
dx: -20
})
]
})
Insert cell
Plot.plot({
width,
x: { label: "", ticks: 3 },
y: { ticks: 6 },
facet: {
data: top5Data,
x: "month",
y: (d) => d.track.artists[0].name,
marginRight: 100,
marginLeft: 100
},
fy: { domain: top5 },
fx: { label: "", domain: domains.month.slice(7) },
padding: 0.1,
marks: [
Plot.frame(),
Plot.dot(
top5Data,
Plot.binY(
{ r: "count" },
{
y: "time",
x: "dayOfMonth",
thresholds: d3.timeMinute.every(30),
// stroke: "purple",
strokeOpacity: 0.5
}
)
)
// Plot.ruleX([15, 30])
]
})
Insert cell
Plot.plot({
width,
x: { label: "" },
y: { ticks: 7 },
facet: {
data: top5Data,
y: (d) => d.track.artists[0].name,
marginLeft: 100,
marginRight: 100
},
fy: { domain: top5 },
marks: [
Plot.frame(),
Plot.dot(
top5Data,
Plot.bin(
{ r: "count" },
{
x: "playedAt",
y: "time",
thresholds: d3.timeMinute.every(15),
// stroke: "purple",
strokeOpacity: 0.5
}
)
),
Plot.ruleX(monthRules, { strokeOpacity: 0.3 })
]
})
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.tickX(data, {
x: "playedAt",
strokeOpacity: 0.1
})
]
})
Insert cell
Plot.plot({
marks: [
Plot.tickX(data, {
x: "time",
strokeOpacity: 0.1
})
]
})
Insert cell
Plot.plot({
marginLeft: 100,
y: { label: "", domain: weekdays, line: true },
x: { label: "", line: true, ticks: false },
color: { scheme: "purples" },
marks: [
Plot.cell(data, Plot.group({ fill: "count" }, { x: "hour", y: "day" })),
Plot.text(data, Plot.group({ text: "count" }, { x: "hour", y: "day" }))
]
})
Insert cell
Plot.plot({
facet: { data: data, y: "month", marginLeft: 100, marginRight: 100 },
fy: { label: "", domain: months.slice(7) },
marginLeft: 100,
y: { label: "", domain: weekdays },
x: { label: "" },
color: { scheme: "purples" },
marks: [
Plot.frame(),
Plot.cell(data, Plot.group({ fill: "count" }, { x: "hour", y: "day" })),
Plot.text(data, Plot.group({ text: "count" }, { x: "hour", y: "day" }))
]
})
Insert cell
Plot.plot({
y: { label: "", domain: months.slice(7), line: true },
x: { label: "Day of Month", line: true },
marginLeft: 80,
color: { scheme: "purples" },
marks: [
Plot.cell(
data,
Plot.group({ fill: "count" }, { x: "dayOfMonth", y: "month" })
),
Plot.text(
data,
Plot.group({ text: "count" }, { x: "dayOfMonth", y: "month" })
)
]
})
Insert cell
Plot.plot({
facet: { data: data, y: "day", marginLeft: 80 },
fy: { label: "", line: true, domain: domains.day },
x: { label: "Time of Day", line: true, domain: domains.timeOfDay },
marginLeft: 80,
color: { scheme: "purples" },
padding: 0.05,
marks: [
Plot.cell(data, Plot.groupX({ fill: "proportion" }, { x: "timeOfDay" })),
Plot.text(
data,
Plot.groupX({ text: "proportion-facet" }, { x: "timeOfDay" })
)
]
})
Insert cell
Plot.plot({
facet: { data: data, y: "timeOfDay", marginLeft: 100 },
fy: { domain: domains.timeOfDay, label: "" },
marks: [
Plot.dot(
data,
Plot.binX(
{ r: "count" },
{
x: "playedAt",
thresholds: d3.timeHour,
strokeOpacity: 0.4,
stroke: "timeOfDay"
}
)
)
]
})
Insert cell
Plot.tickX(data, { x: "playedAt", strokeOpacity: 0.1 }).plot({
facet: {
data: data,
x: "hour",
y: "day",
marginLeft: 100
},
fy: {
//domain: domains.month.slice(7),
domain: domains.day,
label: ""
},
width,
fx: { label: "" },
marks: [
Plot.frame(),
Plot.rect(
data,
Plot.groupZ({ fill: "count" }, { fill: "playedAt", fillOpacity: 0.6 })
)
],
color: {
scheme: "purples"
}
})
Insert cell
Insert cell
filtered_data = data.filter((d) => d.artistsNames.includes(selected_artist))
Insert cell
viewof selected_artist = Inputs.select(top5, { unique: true, sort: true })
Insert cell
Plot.plot({
x: { domain: domains.hour },
color: { scheme: "purples" },
padding: 0,
marks: [
Plot.frame(),
Plot.cell(
filtered_data,
Plot.groupX({ fill: "count" }, { x: "hour", stroke: "black" })
),
Plot.text(filtered_data, Plot.groupX({ text: "count" }, { x: "hour" }))
]
})
Insert cell
Plot.plot({
marks: [
Plot.dot(
filtered_data,
Plot.binX(
{ r: "count" },
{
x: "playedAt",
thresholds: d3.timeHour,
stroke: "purple",
strokeOpacity: 0.3
}
)
)
]
})
Insert cell
Plot.plot({
x: { domain: domains.day, label: "" },
color: { scheme: "purples" },
padding: 0.05,
marks: [
Plot.cell(
filtered_data,
Plot.groupX(
{ fill: "count" },
{
x: "day"
}
)
),
Plot.text(
filtered_data,
Plot.groupX(
{ text: "proportion" },
{
x: "day"
}
)
)
]
})
Insert cell
Plot.tickX(filtered_data, { x: "playedAt", strokeOpacity: 0.3 }).plot({
facet: {
data: filtered_data,
x: "hour",
y: "day",
marginLeft: 80
},
fy: {
domain: domains.day,
label: ""
},
width,
fx: { label: "" },
marks: [
Plot.frame(),
Plot.rect(
filtered_data,
Plot.groupZ(
{ fill: "count" },
{ fill: "playedAt", fillOpacity: 0.6, thresholds: d3.timeHour }
)
)
],
color: {
scheme: "purples"
}
})
Insert cell
Plot.plot({
facet: { data: filtered_data, y: "timeOfDay", marginLeft: 100 },
fy: { domain: domains.timeOfDay, label: "" },
marks: [
Plot.dot(
filtered_data,
Plot.binX(
{ r: "count" },
{
x: "playedAt",
thresholds: d3.timeHour,
strokeOpacity: 0.4,
stroke: "timeOfDay"
}
)
)
]
})
Insert cell
Insert cell
weekdays = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
]
Insert cell
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
Insert cell
timeOfDay = [
"Late night",
"Early morning",
"Morning",
"Afternoon",
"Late afternoon",
"Evening"
]
Insert cell
hours = [...Array(24).keys()]
Insert cell
// Load the Temporal API using a Polyfill
Temporal = {
const TemporalLib = await require("@js-temporal/polyfill@0.3.0");
return TemporalLib.Temporal;
}
Insert cell
domains = ({
month: months,
day: weekdays,
timeOfDay: timeOfDay,
hour: hours
})
Insert cell
artists = data.flatMap((d) => d.artistsNames)
Insert cell
top5 = ["La Plebada", "La Banda Baston", "Fntxy", "Yoga Fire", "Aleman"]
Insert cell
monthRules = d3.timeWeek
.range(
d3.min(artistData.map((d) => d.date)),
d3.max(artistData.map((d) => d.date))
)
.map((d) => new Date(d.setUTCHours(0)))
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