Public
Edited
Apr 28
Insert cell
Insert cell
import {vl} from "@vega/vega-lite-api-v5"
Insert cell
import {printTable} from "@uwdata/data-utilities"
Insert cell
smart_grid = FileAttachment("smart_grid_dataset_3.csv").csv()
Insert cell
smart_gridParsed = smart_grid.map(d => ({
...d,
Timestamp: new Date(d["Timestamp"]),
Solar: +d["Solar Power (kW)"],
Wind: +d["Wind Power (kW)"]
}))

Insert cell
chartData = {
const byHour = d3.rollup(
smart_gridParsed,
v => ({
avgSolar: d3.mean(v, d => d.Solar),
avgWind: d3.mean(v, d => d.Wind)
}),
d => d.Timestamp.getHours()
);

return Array.from(byHour, ([hour, {avgSolar, avgWind}]) => [
{Hour: hour, Source: "Solar", kW: avgSolar},
{Hour: hour, Source: "Wind", kW: avgWind}
])
.flat()
.sort((a, b) => d3.ascending(a.Hour, b.Hour));
}


Insert cell
vl.markLine()
.data(chartData)
.encode(
vl.x().fieldN("Hour")
.axis({title: "Hour of Day (0 – 23)"}),
vl.y().fieldQ("kW")
.title("Average Power (kW)"),
vl.color().fieldN("Source"),
vl.tooltip(["Source", "Hour", "kW"])
)
.width(700)
.height(400)
.title("Average Solar vs Wind Generation by Hour — Flat Night-time Solar Highlights Data Error")
.render()

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
monthlyTotals = {
const byMonth = d3.rollup(
smart_gridParsed,
v => d3.sum(v, d => d["Power Consumption (kW)"]),
d => d.Timestamp.getMonth() // 0‒11
);

return Array.from(byMonth, ([m, total]) => ({
Month: new Date(2024, m).toLocaleString("default", {month:"short"}),
Total: total
})).sort((a, b) => d3.ascending(a.Month, b.Month));
}
Insert cell
vl.markBar()
.data(monthlyTotals)
.encode(
vl.x().fieldN("Month").axis({title:"Month"}),
vl.y().fieldQ("Total").axis({title:"Total kWh"}),
vl.tooltip(["Month","Total"])
)
.width(500)
.height(300)
.title("Total Power Consumption by Month (2024)")
.render()
Insert cell
Insert cell
Insert cell
monthlyCost = {
const byMonth = d3.rollup(
smart_gridParsed,
v => d3.sum(v, d =>
d["Grid Supply (kW)"] * 0.25 * d["Electricity Price (USD/kWh)"]
),
d => d.Timestamp.getMonth()
);
return Array.from(byMonth, ([m, usd]) => ({
Month: new Date(2024, m).toLocaleString("default", {month:"short"}),
USD: usd
})).sort((a,b)=>d3.ascending(a.Month,b.Month));
}
Insert cell
vl.markBar()
.data(monthlyCost)
.encode(
vl.x().fieldN("Month"),
vl.y().fieldQ("USD").axis({title:"Cost in number of thousands (USD)"}),
vl.tooltip(["Month","USD"])
)
.width(480)
.height(280)
.title("Cost of Grid Energy by Month")
.render()
Insert cell
Insert cell
weeklyWaste = {
const byWeek = d3.rollup(
smart_gridParsed,
v => {
const gen = d3.sum(v, d => (d.Solar + d.Wind + d["Grid Supply (kW)"]) * 0.25);
const load = d3.sum(v, d => d["Power Consumption (kW)"] * 0.25);
const waste = Math.max(gen - load, 0);
return {gen, waste, pct: 100 * waste / gen};
},
d => d3.timeWeek.floor(d.Timestamp)
);
return Array.from(byWeek, ([weekStart, o]) => ({
Week: weekStart, Percent: o.pct
})).sort((a,b)=>d3.ascending(a.Week,b.Week));
}
Insert cell
vl.layer(
vl.markBar()
.data(weeklyWaste)
.encode(
vl.x().fieldT("Week").axis({ title: "Week" }),
vl.y().fieldQ("Percent").axis({ title: "Waste (%)" }),
vl.tooltip(["Week", "Percent"])
)
.width(600)
.height(300),

vl.markRule({ strokeDash: [4, 4] })
.data([{ y: 15 }])
.encode(vl.y().value(15))
)
.title("Weekly Energy Waste Percentage (15 % Acceptable Limit)")
.render()

Insert cell
Insert cell
Insert cell
priceRelData = smart_gridParsed.map(d => ({
Price: d["Electricity Price (USD/kWh)"],
Load: d["Power Consumption (kW)"],
Solar: d["Solar Power (kW)"],
Wind: d["Wind Power (kW)"],
Temp: d["Temperature (C)"]
}));
Insert cell
vl.markCircle({ opacity: 0.35 })
.data(priceRelData)
.encode(
vl.x().fieldQ({ repeat: "column" }),
vl.y().fieldQ("Price").title("Price ($/kWh)"),
vl.tooltip(["Price", { repeat: "column" }])
)
.width(130)
.height(130)
.repeat({ column: ["Load", "Solar", "Wind", "Temp"] })
.columns(4)
.title("Electricity Price vs. Other Factors — No Apparent Correlation")
.render()
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