Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
1993cb74d9
|
|||
|
50ae08855b
|
|||
|
dc55012963
|
|||
|
156c32be67
|
|||
|
6e4f6a5009
|
|||
|
5337e434b3
|
|||
|
7a21162dc9
|
|||
|
ccd418a43a
|
|||
|
78b50f902a
|
|||
|
1e8669ecc7
|
|||
|
f33e413893
|
|||
|
f7de9da53a
|
|||
|
b3d5255898
|
|||
|
9a2cef25df
|
|||
|
7a0c64676c
|
|||
|
f9f04f22b4
|
|||
|
f768f88730
|
|||
|
6b304b4b32
|
|||
|
87ee41b55d
|
|||
|
e26b20a017
|
210
app.qmd
Normal file
210
app.qmd
Normal file
@@ -0,0 +1,210 @@
|
||||
---
|
||||
title: "Data Science Methods for Forecasting in Energy and Economics"
|
||||
date: 2025-07-10
|
||||
format:
|
||||
revealjs:
|
||||
embed-resources: true
|
||||
footer: ""
|
||||
execute:
|
||||
daemon: false
|
||||
highlight-style: github
|
||||
---
|
||||
|
||||
```{ojs}
|
||||
d3 = require("d3@7")
|
||||
```
|
||||
|
||||
```{ojs}
|
||||
bsplineData = FileAttachment("basis_functions.csv").csv({ typed: true })
|
||||
```
|
||||
|
||||
```{ojs}
|
||||
function updateChartInner(g, x, y, linesGroup, color, line, data) {
|
||||
// Update axes with transitions
|
||||
x.domain([0, d3.max(data, d => d.x)]);
|
||||
g.select(".x-axis").transition().duration(1500).call(d3.axisBottom(x).ticks(10));
|
||||
y.domain([0, d3.max(data, d => d.y)]);
|
||||
g.select(".y-axis").transition().duration(1500).call(d3.axisLeft(y).ticks(5));
|
||||
|
||||
// Group data by basis function
|
||||
const dataByFunction = Array.from(d3.group(data, d => d.b));
|
||||
const keyFn = d => d[0];
|
||||
|
||||
// Update basis function lines
|
||||
const u = linesGroup.selectAll("path").data(dataByFunction, keyFn);
|
||||
u.join(
|
||||
enter => enter.append("path").attr("fill","none").attr("stroke-width",3)
|
||||
.attr("stroke", (_, i) => color(i)).attr("d", d => line(d[1].map(pt => ({x: pt.x, y: 0}))))
|
||||
.style("opacity",0),
|
||||
update => update,
|
||||
exit => exit.transition().duration(1000).style("opacity",0).remove()
|
||||
)
|
||||
.transition().duration(1000)
|
||||
.attr("d", d => line(d[1]))
|
||||
.attr("stroke", (_, i) => color(i))
|
||||
.style("opacity",1);
|
||||
}
|
||||
|
||||
chart = {
|
||||
// State variables for selected parameters
|
||||
let selectedMu = 0.5;
|
||||
let selectedSig = 1;
|
||||
let selectedNonc = 0;
|
||||
let selectedTailw = 1;
|
||||
const filteredData = () => bsplineData.filter(d =>
|
||||
Math.abs(selectedMu - d.mu) < 0.001 &&
|
||||
d.sig === selectedSig &&
|
||||
d.nonc === selectedNonc &&
|
||||
d.tailw === selectedTailw
|
||||
);
|
||||
const container = d3.create("div")
|
||||
.style("max-width", "none")
|
||||
.style("width", "100%");;
|
||||
const controlsContainer = container.append("div")
|
||||
.style("display", "flex")
|
||||
.style("gap", "20px");
|
||||
// slider controls
|
||||
const sliders = [
|
||||
{ label: 'Mu', get: () => selectedMu, set: v => selectedMu = v, min: 0.1, max: 0.9, step: 0.2 },
|
||||
{ label: 'Sigma', get: () => Math.log2(selectedSig), set: v => selectedSig = 2 ** v, min: -2, max: 2, step: 1 },
|
||||
{ label: 'Noncentrality', get: () => selectedNonc, set: v => selectedNonc = v, min: -4, max: 4, step: 2 },
|
||||
{ label: 'Tailweight', get: () => Math.log2(selectedTailw), set: v => selectedTailw = 2 ** v, min: -2, max: 2, step: 1 }
|
||||
];
|
||||
// Build slider controls with D3 data join
|
||||
const sliderCont = controlsContainer.selectAll('div').data(sliders).join('div')
|
||||
.style('display','flex').style('align-items','center').style('gap','10px')
|
||||
.style('flex','1').style('min-width','0px');
|
||||
sliderCont.append('label').text(d => d.label + ':').style('font-size','20px');
|
||||
sliderCont.append('input')
|
||||
.attr('type','range').attr('min', d => d.min).attr('max', d => d.max).attr('step', d => d.step)
|
||||
.property('value', d => d.get())
|
||||
.on('input', function(event, d) {
|
||||
const val = +this.value; d.set(val);
|
||||
d3.select(this.parentNode).select('span').text(d.label.match(/Sigma|Tailweight/) ? 2**val : val);
|
||||
updateChart(filteredData());
|
||||
})
|
||||
.style('width', '100%');
|
||||
sliderCont.append('span').text(d => (d.label.match(/Sigma|Tailweight/) ? d.get() : d.get()))
|
||||
.style('font-size','20px');
|
||||
// Build SVG
|
||||
const width = 800;
|
||||
const height = 400;
|
||||
const margin = {top: 40, right: 20, bottom: 40, left: 40};
|
||||
const innerWidth = width - margin.left - margin.right;
|
||||
const innerHeight = height - margin.top - margin.bottom;
|
||||
|
||||
// Set controls container width to match SVG plot width
|
||||
controlsContainer.style("max-width", "none").style("width", "100%");
|
||||
// Distribute each control evenly and make sliders full-width
|
||||
controlsContainer.selectAll("div").style("flex", "1").style("min-width", "0px");
|
||||
controlsContainer.selectAll("input").style("width", "100%").style("box-sizing", "border-box");
|
||||
|
||||
// Create scales
|
||||
const x = d3.scaleLinear()
|
||||
.domain([0, 1])
|
||||
.range([0, innerWidth]);
|
||||
|
||||
const y = d3.scaleLinear()
|
||||
.domain([0, 0.7])
|
||||
.range([innerHeight, 0]);
|
||||
|
||||
// Create a color scale for the basis functions
|
||||
const color = d3.scaleOrdinal(d3.schemeCategory10);
|
||||
|
||||
// Create SVG
|
||||
const svg = d3.create("svg")
|
||||
.attr("width", "100%")
|
||||
.attr("height", "auto")
|
||||
.attr("viewBox", [0, 0, width, height])
|
||||
.attr("preserveAspectRatio", "xMidYMid meet")
|
||||
.attr("style", "max-width: 100%; height: auto;");
|
||||
|
||||
// Add chart title
|
||||
// svg.append("text")
|
||||
// .attr("class", "chart-title")
|
||||
// .attr("x", width / 2)
|
||||
// .attr("y", 20)
|
||||
// .attr("text-anchor", "middle")
|
||||
// .attr("font-size", "20px")
|
||||
// .attr("font-weight", "bold");
|
||||
|
||||
// Create the chart group
|
||||
const g = svg.append("g")
|
||||
.attr("transform", `translate(${margin.left},${margin.top})`);
|
||||
|
||||
// Add axes
|
||||
const xAxis = g.append("g")
|
||||
.attr("transform", `translate(0,${innerHeight})`)
|
||||
.attr("class", "x-axis")
|
||||
.call(d3.axisBottom(x).ticks(10))
|
||||
.style("font-size", "20px");
|
||||
|
||||
const yAxis = g.append("g")
|
||||
.attr("class", "y-axis")
|
||||
.call(d3.axisLeft(y).ticks(5))
|
||||
.style("font-size", "20px");
|
||||
|
||||
// Add axis labels
|
||||
// g.append("text")
|
||||
// .attr("x", innerWidth / 2)
|
||||
// .attr("y", innerHeight + 35)
|
||||
// .attr("text-anchor", "middle")
|
||||
// .text("x");
|
||||
|
||||
// g.append("text")
|
||||
// .attr("transform", "rotate(-90)")
|
||||
// .attr("x", -innerHeight / 2)
|
||||
// .attr("y", -30)
|
||||
// .attr("text-anchor", "middle")
|
||||
// .text("y");
|
||||
|
||||
// Add a horizontal line at y = 0
|
||||
g.append("line")
|
||||
.attr("x1", 0)
|
||||
.attr("x2", innerWidth)
|
||||
.attr("y1", y(0))
|
||||
.attr("y2", y(0))
|
||||
.attr("stroke", "#000")
|
||||
.attr("stroke-opacity", 0.2);
|
||||
|
||||
// Add gridlines
|
||||
g.append("g")
|
||||
.attr("class", "grid-lines")
|
||||
.selectAll("line")
|
||||
.data(y.ticks(5))
|
||||
.join("line")
|
||||
.attr("x1", 0)
|
||||
.attr("x2", innerWidth)
|
||||
.attr("y1", d => y(d))
|
||||
.attr("y2", d => y(d))
|
||||
.attr("stroke", "#ccc")
|
||||
.attr("stroke-opacity", 0.5);
|
||||
|
||||
// Create a line generator
|
||||
const line = d3.line()
|
||||
.x(d => x(d.x))
|
||||
.y(d => y(d.y))
|
||||
.curve(d3.curveBasis);
|
||||
|
||||
// Group to contain the basis function lines
|
||||
const linesGroup = g.append("g")
|
||||
.attr("class", "basis-functions");
|
||||
|
||||
// Store the current basis functions for transition
|
||||
let currentBasisFunctions = new Map();
|
||||
|
||||
// Function to update the chart with new data
|
||||
function updateChart(data) {
|
||||
updateChartInner(g, x, y, linesGroup, color, line, data);
|
||||
}
|
||||
|
||||
// Store the update function
|
||||
svg.node().update = updateChart;
|
||||
|
||||
// Initial render
|
||||
updateChart(filteredData());
|
||||
|
||||
container.node().appendChild(svg.node());
|
||||
return container.node();
|
||||
}
|
||||
```
|
||||
71
test.R
Normal file
71
test.R
Normal file
@@ -0,0 +1,71 @@
|
||||
# %%
|
||||
library(profoc)
|
||||
library(ggplot2)
|
||||
library(tidyr)
|
||||
library(dplyr)
|
||||
library(readr)
|
||||
|
||||
# Creating faceted plots for different knot values and mu values
|
||||
# Create a function to generate the data for a given number of knots and mu value
|
||||
generate_basis_data <- function(num_knots, mu_value, sig_value, nonc_value, tailw_value, deg_value) {
|
||||
grid <- seq(from = 0.01, to = 0.99, length.out = 50)
|
||||
# Use provided degree
|
||||
B <- profoc:::make_basis_matrix(grid,
|
||||
profoc::make_knots(
|
||||
n = num_knots,
|
||||
mu = mu_value,
|
||||
sig = sig_value,
|
||||
nonc = nonc_value,
|
||||
tailw = tailw_value,
|
||||
deg = deg_value
|
||||
),
|
||||
deg = deg_value
|
||||
)
|
||||
B_mat <- round(as.matrix(B),2)
|
||||
df <- as.data.frame(B_mat)
|
||||
df$x <- round(grid,2)
|
||||
df_long <- pivot_longer(df,
|
||||
cols = -x,
|
||||
names_to = "b",
|
||||
values_to = "y"
|
||||
)
|
||||
df_long$knots <- num_knots
|
||||
df_long$mu <- mu_value
|
||||
df_long$sig <- sig_value
|
||||
df_long$nonc <- nonc_value
|
||||
df_long$tailw <- tailw_value
|
||||
df_long$deg <- deg_value
|
||||
return(df_long)
|
||||
}
|
||||
|
||||
# Generate data for each combination of knot, mu, sig, nonc, tailw, and deg
|
||||
knot_values <- c(10)
|
||||
mu_values <- seq(0.1, 0.9, by = 0.2)
|
||||
sig_values <- 2^(-2:2)
|
||||
nonc_values <- c(-4,-2,0,2,4)
|
||||
tailw_values <- 2^(-2:2)
|
||||
|
||||
# Create an empty list to store all combinations
|
||||
all_data <- list()
|
||||
counter <- 1
|
||||
|
||||
# Nested loops to cover all parameter combinations
|
||||
for (k in knot_values) {
|
||||
print(paste("Processing knots:", k))
|
||||
for (m in mu_values) {
|
||||
print(paste("Processing mu:", m))
|
||||
for (s in sig_values) {
|
||||
for (nc in nonc_values) {
|
||||
for (tw in tailw_values) {
|
||||
all_data[[counter]] <- generate_basis_data(5, m, s, nc, tw, 2)
|
||||
counter <- counter + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Combine all data frames
|
||||
all_data <- bind_rows(all_data)
|
||||
|
||||
write_csv(all_data, "basis_functions.csv")
|
||||
Reference in New Issue
Block a user