Public
Edited
May 18, 2022
2 forks
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Inputs.table(atlasTable.table)
Insert cell
Insert cell
Insert cell
Inputs.table(atlasTable.outside)
Insert cell
{
const div = document.getElementById("heatMap1") || DOM.element("div");

const names = atlasTable.table.map((e) => e.name);

var data = [
{
z: corrCoefMat.mat,
x: names,
y: names,
type: "heatmap"
}
];

const layout = {
title: "heatmap",
width: width / 2,
height: width / 2
// yaxis: {ytfvtyf
// automargin: true,
// tickangle: 45
// },
};

Plotly.newPlot(div, data, layout);
return md`Draw to heatMap1`;
}
Insert cell
{
const a = [1, 2, 3];
return a.pop(2), a;
}
Insert cell
{
const div = document.getElementById("degreesHist1") || DOM.element("div");

const names = atlasTable.table.map((e) => e.name);
const groups = atlasTable.table.map((e) => e.group);

const traces = [];

const layout = {
title: "Corrcoef of each Atlas",
width: width,
xaxis: {
automargin: true
},
yaxis: {
automargin: true,
tickangle: 45
},
height: 20 * names.length
};

for (let j = 0; j < names.length; ++j) {
let x = corrCoefMat.mat[j];
let name = names[j];
let legendgroup = groups[j];
let marker = { color: d3.schemeTableau10[groups[j]] };
let type = "box";
traces.push({ x, name, legendgroup, type, marker });
}

Plotly.newPlot(div, traces, layout);
return md`Draw to degreeHist1`;
}
Insert cell
graph = {
const table = atlasTable.table;
const mat = corrCoefMat.mat;
const n = numAtlas - corrCoefMat.zeroOut.length;

const nodes = [];
const links = [];

for (const rec of table) {
let { id, group, name } = rec;
nodes.push({ id, group, name });
}

for (let j = 0; j < n; ++j) {
for (let k = j + 1; k < n; ++k) {
let source = table[j].id;
let target = table[k].id;
let value = mat[j][k];
if (value > coefThreshold) {
links.push({ source, target, value });
}
}
}

return { nodes, links };
}
Insert cell
atlasTable = {
const rawTable = rawAtalsTable;
const { zeroOut } = corrCoefMat;
const group = atlasGroups;
const table = [];
const outside = [];

for (let j = 0; j < rawTable.length; ++j) {
if (zeroOut.includes(j)) {
outside.push(rawTable[j]);
continue;
}
let { name, x, y, z, idx } = rawTable[j];
// name = shortName(name);
let id = idx;
let group = -1;
table.push({ name, x, y, z, idx, id, group });
}

for (let j = 0; j < atlasGroups.length; ++j) {
let group = atlasGroups[j];
group.map((e) => (table[e].group = j));
}

return { table, outside };
}
Insert cell
atlasGroups = kmClusters(corrCoefMat.mat)
Insert cell
corrCoefMat = {
const txt = rawCorrCoef;
const split = txt.split(",");

const mat1 = [];
const zeroOut = [];
let ptr = 0;
for (let j = 0; j < numAtlas; ++j) {
let vec = [];

for (let k = 0; k < numAtlas; ++k) {
let v = parseFloat(split[ptr++]);
vec.push(v);
}

vec[j] = 0;

if (sum(vec) == 0) {
zeroOut.push(j);
} else {
mat1.push(vec);
}
}

const mat = [];
for (const vec1 of mat1) {
let vec = [];
for (let j = 0; j < vec1.length; ++j) {
if (!zeroOut.includes(j)) {
vec.push(vec1[j]);
}
}
mat.push(vec);
}

return { mat, zeroOut };
}
Insert cell
numAtlas = 96
Insert cell
## Toolbox
Insert cell
// Copyright 2021 Observable, Inc.
// Released under the ISC license.
// https://observablehq.com/@d3/force-directed-graph
function ForceGraph(
{
nodes, // an iterable of node objects (typically [{id}, …])
links // an iterable of link objects (typically [{source, target}, …])
},
{
nodeId = (d) => d.id, // given d in nodes, returns a unique identifier (string)
nodeGroup, // given d in nodes, returns an (ordinal) value for color
nodeGroups, // an array of ordinal values representing the node groups
nodeTitle, // given d in nodes, a title string
nodeFill = "currentColor", // node stroke fill (if not using a group color encoding)
nodeStroke = "#fff", // node stroke color
nodeStrokeWidth = 1.5, // node stroke width, in pixels
nodeStrokeOpacity = 1, // node stroke opacity
nodeRadius = 5, // node radius, in pixels
nodeStrength,
linkSource = ({ source }) => source, // given d in links, returns a node identifier string
linkTarget = ({ target }) => target, // given d in links, returns a node identifier string
linkStroke = "#999", // link stroke color
linkStrokeOpacity = 0.6, // link stroke opacity
linkStrokeWidth = 1.5, // given d in links, returns a stroke width in pixels
linkStrokeLinecap = "round", // link stroke linecap
linkStrength,
colors = d3.schemeTableau10, // an array of color strings, for the node groups
width = 800, // outer width, in pixels
height = 800, // outer height, in pixels
invalidation // when this promise resolves, stop the simulation
} = {}
) {
// Compute values.
const N = d3.map(nodes, nodeId).map(intern);
const LS = d3.map(links, linkSource).map(intern);
const LT = d3.map(links, linkTarget).map(intern);
if (nodeTitle === undefined) nodeTitle = (_, i) => N[i];
const T = nodeTitle == null ? null : d3.map(nodes, nodeTitle);
const G = nodeGroup == null ? null : d3.map(nodes, nodeGroup).map(intern);
const W =
typeof linkStrokeWidth !== "function"
? null
: d3.map(links, linkStrokeWidth);
const L = typeof linkStroke !== "function" ? null : d3.map(links, linkStroke);

// Replace the input nodes and links with mutable objects for the simulation.
nodes = d3.map(nodes, (_, i) => ({ id: N[i] }));
links = d3.map(links, (_, i) => ({ source: LS[i], target: LT[i] }));

// Compute default domains.
if (G && nodeGroups === undefined) nodeGroups = d3.sort(G);

// Construct the scales.
const color = nodeGroup == null ? null : d3.scaleOrdinal(nodeGroups, colors);

// Construct the forces.
const forceNode = d3.forceManyBody();
const forceLink = d3.forceLink(links).id(({ index: i }) => N[i]);
if (nodeStrength !== undefined) forceNode.strength(nodeStrength);
if (linkStrength !== undefined) forceLink.strength(linkStrength);

const simulation = d3
.forceSimulation(nodes)
.force("link", forceLink)
.force("charge", forceNode)
.force("center", d3.forceCenter())
.force("radius", d3.forceRadial(d3.min([width, height]) / 3, 0, 0))
.on("tick", ticked);

const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "max-width: 100%; height: auto; height: intrinsic;");

const textOpacity = 0.7;
const text = svg
.append("g")
.attr("fill", nodeFill)
.attr("fill-opacity", textOpacity)
.attr("stroke", nodeStroke)
.attr("stroke-opacity", textOpacity)
.attr("stroke-width", 0.1)
.selectAll("circle")
.data(nodes)
.join("text")
.text((d) => {
return d.id;
});

const link = svg
.append("g")
.attr("stroke", typeof linkStroke !== "function" ? linkStroke : null)
.attr("stroke-opacity", linkStrokeOpacity)
.attr(
"stroke-width",
typeof linkStrokeWidth !== "function" ? linkStrokeWidth : null
)
.attr("stroke-linecap", linkStrokeLinecap)
.selectAll("line")
.data(links)
.join("line");

const node = svg
.append("g")
.attr("fill", nodeFill)
.attr("stroke", nodeStroke)
.attr("stroke-opacity", nodeStrokeOpacity)
.attr("stroke-width", nodeStrokeWidth)
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("r", nodeRadius)
.call(drag(simulation));

if (W) link.attr("stroke-width", ({ index: i }) => W[i]);
if (L) link.attr("stroke", ({ index: i }) => L[i]);
if (G) {
node.attr("fill", ({ index: i }) => color(G[i]));
text.attr("stroke", ({ index: i }) => color(G[i]));
text.attr("fill", ({ index: i }) => color(G[i]));
}
if (T) node.append("title").text(({ index: i }) => T[i]);
if (invalidation != null) invalidation.then(() => simulation.stop());

function intern(value) {
return value !== null && typeof value === "object"
? value.valueOf()
: value;
}

const ii = 100;

function ticked() {
// nodes[ii].x = 0;
// nodes[ii].y = 0;

node.attr("cx", (d, i) => d.x).attr("cy", (d, i) => d.y);

text.attr("x", (d, i) => d.x).attr("y", (d, i) => d.y);

link
.attr("x1", (d, i) => d.source.x)
.attr("y1", (d, i) => d.source.y)
.attr("x2", (d, i) => d.target.x)
.attr("y2", (d, i) => d.target.y);
}

function drag(simulation) {
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}

function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}

function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}

return d3
.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}

return Object.assign(svg.node(), { scales: { color } });
}
Insert cell
Insert cell
lastKColumn = (mat, k) => {
for (let i = 0; i < mat.length; i++) {
mat[i] = mat[i].slice(-k);
}

const ns = [];
for (let i = 0; i < k; i++) {
ns.push(norm2([...mat.map((e) => e[i])]));
}

for (let i = 0; i < mat.length; i++) {
for (let j = 0; j < k; j++) {
mat[i][j] /= ns[j];
}
}

return mat;
}
Insert cell
firstKColumn = (mat, k) => {
for (let i = 0; i < mat.length; i++) {
mat[i] = mat[i].slice(0, k);
}

const ns = [];
for (let i = 0; i < k; i++) {
ns.push(norm2([...mat.map((e) => e[i])]));
}

for (let i = 0; i < mat.length; i++) {
for (let j = 0; j < k; j++) {
mat[i][j] /= ns[j];
}
}

return mat;
}
Insert cell
norm2 = (vec) => {
let s = 0;
for (let i = 0; i < vec.length; i++) {
s += vec[i] ** 2;
}
return s ** 0.5;
}
Insert cell
sum = (vec) => {
let sum = 0;
vec.map((e) => (sum += e));
return sum;
}
Insert cell
kmClusters = (matCopy, k = numCluster) => {
const mat = [...matCopy];

const lapMat = laplacianMatrix(mat);

let { u, q, v } = svd.SVD(lapMat);

console.log("-----");
console.log(lapMat);
console.log(u, q, v);

// u = lastKColumn(u, k);
u = firstKColumn(u, k);

let km = kmeans.clusterize(u, { k: k }, (err, res) => {
if (err) console.error(err);
});
let { groups } = km;

let clusters = [];
for (let i in groups) {
clusters.push(groups[i].clusterInd);
}
return clusters;
}
Insert cell
laplacianMatrix = (mat) => {
// Laplacian matrix is computes as
// L = D - W
// D: Degree matrix, diagonal matrix, the values are the sum of the weights;
// W: Weight matrix.
const lapMat = [];
for (let j = 0; j < mat.length; ++j) {
let vec = [...mat[j].map((e) => e)];
let s = sum(vec);
vec = vec.map((e) => -e / s);
vec[j] = 1;
lapMat.push(vec);
}
return lapMat;
}
Insert cell
d3 = require("https://d3js.org/d3.v7.min.js")
Insert cell
Plotly = require("https://cdn.plot.ly/plotly-latest.min.js")
Insert cell
kmeans = require("https://bundle.run/node-kmeans@1.1.9")
Insert cell
svd = require("https://bundle.run/svd-js@1.1.1")
Insert cell
## Resources
Insert cell
rawAtalsTable = await FileAttachment("atlas_table (1).csv").csv()
Insert cell
rawCorrCoef1 = await FileAttachment("mean_corrcoef.txt").text()
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