in code/decision-tree/js/EntropyBubble.js [377:492]
drawEntropyLine() {
const self = this;
// loop and create permutations of samples for self.numCirclesPerGroup
let permutations = [];
let data = [];
for (let i = 0; i <= self.numCirclesPerGroup; ++i) {
let j = self.numCirclesPerGroup - i;
// add i positive cases
let positiveSamples = new Array(j).fill("positive");
// append j negative cases
let negativeSamples = new Array(i).fill("negative");
let permutation = positiveSamples.concat(negativeSamples);
// append to permutations array
permutations.push(permutation);
// create data for plot
data.push({
entropy: entropy(permutation),
x: prob(permutation),
});
}
// Create entropy plot
const padding = 50;
const areaGradient = this.svg
.append("defs")
.append("linearGradient")
.attr("id", "areaGradient")
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "0%")
.attr("y2", "100%");
areaGradient
.append("stop")
.attr("offset", "0%")
.attr("stop-color", "rgb(188, 111, 177)")
.attr("stop-opacity", 0.76);
areaGradient
.append("stop")
.attr("offset", "100%")
.attr("stop-color", "white")
.attr("stop-opacity", 0);
this.xScale = scaleLinear()
.domain([0, 1])
.range([this.positionXScale(2), this.positionXScale(8)]);
// .range([padding, this.WIDTH - padding])6
this.yScale = scaleLinear()
.domain([0, 1])
.range([this.HEIGHT - padding, padding * 3]);
// add axes
// x
this.entroypG
.append("g")
.attr("id", "entropy-x-axis")
.attr("transform", `translate(${0}, ${this.HEIGHT - padding})`)
.call(
axisBottom(this.xScale)
.tickFormat((x) => `${format(".0%")(x)}`)
.ticks(5)
);
// y
this.entroypG
.append("g")
.attr("id", "entropy-y-axis")
.attr("transform", `translate(${self.positionXScale(2)}, 0)`)
.call(
axisLeft(this.yScale)
.tickSize(-self.positionXScale(9) + self.positionXScale(3))
.tickSizeOuter(0)
.ticks(4)
);
// draw line
this.entroypG
.append("path")
.datum(data)
.style("fill", "url(#areaGradient)")
.attr("stroke", "rgb(188, 111, 177)")
.attr("stroke-width", 6)
.attr(
"d",
line()
.x((d) => this.xScale(d.x))
.y((d) => this.yScale(d.entropy))
);
// // add title
this.entroypG
.append("text")
.attr("class", "entropy-x-axis")
.text(`Proportion of Positive Class`)
.attr("x", this.WIDTH / 2)
.attr("y", this.HEIGHT - padding + 40)
.attr("text-anchor", "middle");
this.entroypG
.append("text")
.text(mmobile ? "Negative" : "Negative Class")
.attr("x", self.positionXScale(0))
.attr("y", self.positionYScale(4))
.attr("text-anchor", "middle")
.attr("class", "entropy-class-label");
this.entroypG
.append("text")
.text(mmobile ? "Positive" : "Positive Class")
.attr("x", self.positionXScale(10))
.attr("y", self.positionYScale(4))
.attr("text-anchor", "middle")
.attr("class", "entropy-class-label");
}