Public
Edited
Mar 11, 2023
2 forks
Insert cell
Insert cell
chart = plotVolcano(data)
Insert cell
data = FileAttachment("TestList@3.csv").csv();
Insert cell
function plotVolcano(data){
var w = 600,
h = 400;

var margin = {
top: 50,
right: 50,
bottom: 50,
left: 50,
};
var regionWidth = w/2;
var pointA = regionWidth,
pointB = w - regionWidth;


var maxValue = Math.max(
d3.max(data, function(d) { return d.log2FoldChange; }),
Math.abs(d3.min(data, function(d) { return d.log2FoldChange; }))
);
var maxYValue = Math.ceil(d3.max(data, function(d) { return d.neglog10pval; }));
console.log('max value: ',maxValue)
var minValue = -maxValue//Math.min(
//) d3.min(data, function(d) { return d.log2FoldChange; }),
// d3.min(data, function(d) { return d.log2FoldChange; })
//);
console.log('min value: ',minValue)


const svg = d3.create("svg")
.attr("id",'volcanoplot')
.attr('width', margin.left + w + margin.right)
.attr('height', margin.top + h + margin.bottom)
.attr('padding',50)
.attr('transform', translation(margin.left, margin.top));

const Up = svg.append("text")
.attr("fill", "black")
.attr("x", w/4+margin.left)
.attr("y", 15)
.attr("text-anchor", "middle")
.text("Down Regulated");

const Down = svg.append("text")
.attr("fill", "black")
.attr("x", 3*(w/4)+margin.left)
.attr("y", 15)
.attr("text-anchor", "middle")
.text("Up Regulated");

var xScale = d3.scaleLinear()
.domain([-maxValue, maxValue])
.range([0, w])
.nice();

var yScale = d3.scaleLinear()
.domain([maxYValue, 0])
.range([0, h-margin.top])
.nice();

var xAxis = d3.axisBottom(xScale)
.ticks(5);

var yAxis = d3.axisLeft(yScale)
.ticks(5);
// .tickSize(4,0)
// .tickPadding(3);

svg.append('g')
.attr('class', 'axis x')
.attr('transform', translation(margin.left, h))//h+margin.top))
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'middle');
svg.append('g')
.attr('class', 'axis y')
.attr('transform', translation(margin.left, margin.top))//margin.top))
.call(yAxis)
.selectAll('text')
.style('text-anchor', 'left');

svg.append('line')
.style("stroke", "black")
.style("stroke-width", 1)
.attr('x1', regionWidth+margin.left )
.attr('x2', regionWidth+margin.left )
.attr('y1', margin.top )
.attr('y2', h );

// nodeGroups = []
// colors = d3.schemeTableau10;
// const color = d3.scaleOrdinal(nodeGroups, colors);
var color = d3.scaleOrdinal()
.domain(["No", "Down", "Up" ])
.range([ "#8a8a8a", "#cc0000", "#009933"])
svg
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', d => xScale(d.log2FoldChange)+margin.left)
.attr('cy', d => yScale(d.neglog10pval)+margin.top)
.attr('r', 3)
.attr('opacity',0.5)
.attr("fill", d => color(d.change))
.append("title").text(function(d) { return d.Label+'\n'+'-log10(pValue): '+parseFloat(d.neglog10pval).toFixed(2)+'\n'+'log2FoldChange: '+parseFloat(d.log2FoldChange).toFixed(2)});
// string concatenation for translations
function translation(x,y) {
return 'translate(' + x + ',' + y + ')';
}
return svg.node()
}
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