Half-donut percentage values - vue.js

Need help with D3.js I have a half-donut component which receives 2 values a value variable and a threshold variable I need to place a cutting arc on the half donut based on the threshold value which is between 0 and 1 where 1 is 100%.
The half-donut component what I have .
The dashed line I need is above.

The code below will do this. Later I will add the link to the tutorial.
import * as d3 from 'd3';
import { attrs } from 'd3-selection-multi'
let btn = d3.select('body').append('button').text('Change data')
.style('margin-bottom', '10px')
let dim = { 'width': 700, 'height': 400 }
let svg = d3.select('body').append('svg').attrs(dim)
.style('border', '1px solid black')
let g = svg.append('g').attr('transform', 'translate(350, 370)')
let arcGen = d3.arc()
arcGen.innerRadius(250).outerRadius(340)
let pth = arcGen({
startAngle: -Math.PI / 2,
endAngle: Math.PI / 2
})
let scale = d3.scaleLinear([0, 1], [-Math.PI / 2, Math.PI / 2])
let data = [Math.random(), Math.random()]
g.append('path').attrs({
'd': pth,
'fill': 'lightgray',
'stroke': 'black'
})
svg.append('clipPath').attr('id', 'mask')
.append('path').attr('d', pth)
let valuePth = arcGen({
startAngle: -Math.PI / 2,
endAngle: scale(data[0])
})
let value = g.append('path').attrs({
'd': valuePth,
'fill': data[0] < data[1]? 'aquamarine': 'lightcoral',
'stroke': 'black'
})
// target line
let pts = d3.pointRadial(scale(data[1]), 0).concat(d3.pointRadial(scale(data[1]), 1000))
let target = g.append('line').attrs({
'x1': pts[0], 'y1': pts[1], 'x2': pts[2], 'y2': pts[3],
'stroke': 'midnightblue',
'stroke-width': 4,
'stroke-dasharray': '6, 3',
'clip-path': 'url(#mask)'
})
btn.on('click', ()=>{
let oldAngle = scale(data[0])
data = [Math.random(), Math.random()]
pts = d3.pointRadial(scale(data[1]), 0).concat(d3.pointRadial(scale(data[1]), 1000))
value.transition().duration(2000).attrTween('d', ()=>{
let start = {startAngle: -Math.PI / 2, endAngle: oldAngle}
let interpolate = d3.interpolate(start, {startAngle: -Math.PI / 2, endAngle: scale(data[0])})
return (t)=>arcGen(interpolate(t))
}).attr('fill', data[0] < data[1]? 'aquamarine': 'lightcoral')
target.transition().duration(2000).attrs({
'x1': pts[0], 'y1': pts[1], 'x2': pts[2], 'y2': pts[3]
})
})

Related

How do I set legend element titles?

I am using code from this biostars post to get myself more acquainted with creating plots in ggplot. I am a bit stuck on setting the legend variables though
Is there a way to set the colour and control the number of breaks/dots in the legend (under numDEInCat)
term <-c("snoRNA binding", "preprophase band", "kinesin complex", "microtubule motor activity", "DNA replication")
fc <-runif(5, 1.00, 5.00)
padj_BH <-runif(5, 0.001, 0.05)
numDEInCat <-runif(5, 30, 300)
ggdata <- data.frame(term,fc,padj_BH, numDEInCat)
gg1 <- ggplot(ggdata,
aes(x = term, y = fc, size = numDEInCat, color = padj_BH)) +
expand_limits(y = 1) +
geom_point(shape = 16,inherit.aes = T) +
scale_size(range = c(2.5,12.5)) +
scale_color_gradient(low= "#ff0303",
high="#1e00b3")+ #colour for p value
xlab('') + ylab('Fold Enrichment') + #lavel fold enrichment axis
labs(
title = "Gene Ontology all",
subtitle = 'BH-adjusted',
caption = '',
color="Adjusted P-value", #label the aacolor
size="count") + #label dot size
theme_bw(base_size = 24) +
theme(
legend.position = 'right',
legend.background = element_rect(),
plot.title = element_text(angle = 0, size = 16, face = 'bold', vjust = 1),
plot.subtitle = element_text(angle = 0, size = 14, face = 'bold', vjust = 1),
plot.caption = element_text(angle = 0, size = 12, face = 'bold', vjust = 1),
axis.text.x = element_text(angle = 0, size = 12, face = 'bold', hjust = 1.10),
axis.text.y = element_text(angle = 0, size = 12, face = 'bold', vjust = 0.5),
axis.title = element_text(size = 12, face = 'bold'),
axis.title.x = element_text(size = 12, face = 'bold'),
axis.title.y = element_text(size = 12, face = 'bold'),
axis.line = element_line(colour = 'black'),
#Legend
legend.key = element_blank(), # removes the border
legend.key.size = unit(1, "cm"), # Sets overall area/size of the legend
legend.text = element_text(size = 14, face = "bold"), # Text size
title = element_text(size = 14, face = "bold")) +
coord_flip()
gg1
I think what you're looking for are guides(size = guide_legend(override.aes(BLABLA))) and scale_size(breaks = c(BLABLA))
gg1 +
guides(size = guide_legend(override.aes = list(colour = "red"))) +
scale_size(limits = c(1, 1000), breaks = c(10, 500, 1000))
Created on 2021-11-18 by the reprex package (v2.0.1)

How to use Animated.timing on a new Animated.ValueXY()

With const animation = new Animated.ValueXY() I can do
Animated.timing(animation, { toValue: 0, duration: 500})
How can I accomplish this on both X and Y with const animation = new Animated.ValueXY()?
The same way as initializing the values to const animation = new Animated.ValueXY({x: 0, y: 0}):
Animated.timing(animation, {
toValue: {x: 0, y: 0},
duration: 500
})
Behavior is the same for all Animated.ValueXY related operations. {x: num, y: num} instead of a number.

Tensorflow structure search

I am trying to implement a structure search mechanism, find blocks and wrap them in a block.
I am new to machine learning, at first I started with the brain.js This library is quite simple and clear, I realized what was happening from the first time, the library is suitable for simple tasks.
But unfortunately, this library is not functional, earlier I asked how to find blocks: How to take the data?
I decided to try tensorflow, but for understanding this library is difficult, I still do not understand how it learns, because there is input and what the result should be.
Here is an example of how I tried to do a search for a brain.js
https://jsfiddle.net/eoy7krzj/
<html>
<head>
<script src="https://cdn.rawgit.com/BrainJS/brain.js/5797b875/browser.js"></script>
</head>
<body>
<div>
<button onclick="train()">train</button><button onclick="Generate.next(); Generate.draw();">generate</button><button onclick="calculate()">calculate</button>
</div>
<canvas id="generate" style="border: 1px solid #000"></canvas>
</body>
<script type="text/javascript">
var trainData = [];
function randomInteger(min, max) {
var rand = min - 0.5 + Math.random() * (max - min + 1)
//rand = Math.round(rand);
return rand;
}
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
var Generate = new function(){
var canvas = document.getElementById('generate');
var ctx = canvas.getContext('2d');
var elem = {
input: [],
output: []
}
var size = {
width: 240,
height: 140
}
canvas.width = 500;
canvas.height = 250;
this.next = function(){
this.build();
trainData.push({
input: elem.input,
output: elem.output
});
}
this.clear = function(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
this.draw = function(){
this.clear();
this.item(elem.input, function(item){
ctx.strokeStyle = "green";
ctx.strokeRect(item[0], item[1], item[2], item[3]);
})
this.item(elem.output, function(item){
ctx.strokeStyle = "blue";
ctx.strokeRect(item[0], item[1], item[2], item[3]);
})
}
this.item = function(where, call){
for (var i = 0; i < where.length; i+=4) {
var input = [
where[i],
where[i+1],
where[i+2],
where[i+3],
];
this.denormalize(input);
call(input)
}
}
this.normalize = function(input){
input[0] = input[0] / 500;
input[1] = input[1] / 250;
input[2] = input[2] / 500;
input[3] = input[3] / 250;
}
this.denormalize = function(input){
input[0] = input[0] * 500;
input[1] = input[1] * 250;
input[2] = input[2] * 500;
input[3] = input[3] * 250;
}
this.empty = function(add){
var data = [];
for (var i = 0; i < add; i++) {
data = data.concat([0,0,0,0]);
}
return data;
}
this.build = function(){
var output = [];
var input = [];
size.width = randomInteger(100,500);
size.height = randomInteger(50,250);
var lines = 1;//Math.round(size.height / 100);
var line_size = 0;
var line_offset = 0;
for(var i = 0; i < lines; i++){
line_size = randomInteger(30,Math.round(size.height / lines));
var columns = Math.round(randomInteger(1,3));
var columns_width = 0;
var columns_offset = 0;
for(var c = 0; c < columns; c++){
columns_width = randomInteger(30,Math.round(size.width / columns));
var item = [
columns_offset + 10,
line_offset + 10,
columns_width - 20,
line_size - 20
];
this.normalize(item);
input = input.concat(item);
columns_offset += columns_width;
}
var box = [
0,
line_offset,
columns_offset,
line_size
]
this.normalize(box);
output = output.concat(box);
line_offset += line_size + 10;
}
elem.input = input.concat(this.empty(5 - Math.round(input.length / 4)));
elem.output = output.concat(this.empty(2 - Math.round(output.length / 4)));
}
this.get = function(){
return elem.input;
}
this.calculate = function(result, stat){
console.log('brain:',result);
this.item(result, function(item){
ctx.strokeStyle = "red";
ctx.strokeRect(item[0], item[1], item[2], item[3]);
})
}
this.train = function(){
for(var i = 0; i < 1400; i++){
this.next();
}
}
}
Generate.train();
Generate.log = true;
var net,stat;
function train(){
net = new brain.NeuralNetwork({ hiddenLayers: [4],activation: 'tanh'});
stat = net.train(trainData,{log: true, iterations: 1250,learningRate: 0.0001,errorThresh:0.0005});
console.log('stat:',stat)
}
function calculate(){
Generate.calculate(net.run(Generate.get()))
}
</script>
</html>
My goal is to train the network to find the elements and show their sizes.
Procedure: Click to train Click generate Click to calculate
The blue block wraps the green blocks, this should be the result, the red block shows that it has found a neural network.
That's what interests me:
Can tensorflow find blocks?
The data should be in the form of pictures, or numerical data?
How do you advise to start?
I would be very grateful if someone would put a small example on how to receive data, in what format and how to train)
Edit
I give the size and position of the green blocks, the goal is to find where the green blocks are and their total size, as an example this is shown by the blue block.
Neural Network
The neural network has a fix input that are the number of green blocks. Lets suppose we are going to find 3 blocks in a picture. The model will have an InputShape of [3, 4] for each block has 4 coordinates (x, y, w, h). The predicted box can be the min(x), min(y), max(x+w), max(y+h). This bounding box will wrap the boxes.
A sample data can be
features = [[[1, 2, 3, 4], [2, 4, 5, 6], [3, 4, 2, 2]]]
labels = [[1, 2, 7, 10]]
const random = _ => Math.floor(Math.random()*100)
const generate = _ => {
xarr = Array.from({length: 3}, _ => random())
yarr = Array.from({length: 3}, _ => random())
features = xarr.map((x, i) => ([x, yarr[i], x + random(), yarr[i] + random()]))
labels = features.reduce((acc, f) => ([Math.min(acc[0], f[0]), Math.min(acc[1], f[1]), Math.max(acc[0] + acc[2], f[0] + f[2]), Math.max(acc[0] + acc[3], f[1] + f[3])]) )
return {features, labels}
}
(async () => {
const model = tf.sequential();
model.add(tf.layers.dense({units: 20, inputShape: [3, 4], activation: 'relu'}));
model.add(tf.layers.reshape({targetShape: [60]}));
model.add(tf.layers.dense({units: 4, activation: 'relu'}));
model.summary();
// Prepare the model for training: Specify the loss and the optimizer.
model.compile({loss: 'meanSquaredError', optimizer: 'adam'});
// Generate some synthetic data for training.
let x = [];
let y = [];
for (let i = 0; i < 5; i++) {
const data = generate();
x.push(data.features);
y.push(data.labels);
}
const xs = tf.tensor3d(x);
const ys = tf.tensor2d(y);
console.log(xs.shape);
console.log(ys.shape);
// Train the model using the data then do inference on a data point the
// model hasn't seen:
xs.print()
ys.print()
await model.fit(xs, ys, {epochs: 100});
model.predict(tf.tensor([[[1, 2, 3, 4], [2, 4, 5, 6], [3, 4, 2, 2]]])).print();
})();
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/#tensorflow/tfjs#latest"> </script>
</head>
<body>
</body>
</html>
Convolutionnal filters
The previous model will generate boxes that wraps up boxes whose coordinates are given to the model. But if we are to find out which position are the matching boxes, one can use a convolution filter.
Let's suppose we want to match the following data [[1, 2], [5, 6]] in a tensor.
This data can be a cropped picture that we want to see if it exists or not in a big picture and if yes, how many times it appears. Using a convolution filter of [[1, 1], [1, 1]], we will have a result of 14 at the top left coordinates (x, y) where there is a match. Filtering over this value (14) will return the index of the coordinates of interest.
(async() => {
// tf.setBackend('cpu')
const arr = Array.from({length: 16}, (_, k) => k+1)
const x = tf.tensor([...arr, ...arr.reverse()], [8, 4]); // input image 2d
x.print()
const filter = tf.ones([2, 2]) // input filter 2d
const conv = x.reshape([1, ...x.shape, 1]).conv2d(filter.reshape([...filter.shape, 1, 1]), 1, 'same').squeeze()
conv.print() // conv
const part = tf.tensor([[1, 2], [5, 6]]) // searched tensor
const mask = conv.equal(part.sum()).asType('bool');
const coords = await tf.whereAsync(mask);
coords.print(); // (0, 0) and (4, 0) are the top left coordinates of part of x that matches the part tensor
// how many elements matches
console.log(coords.shape[0])
// filter coords
const [a, b] = coords.lessEqual(x.shape.map((a, i) => a - part.shape[i] )).split(2, 1); // because of padding 'same'
const filterMask = a.mul(b)
const filterCoords = await tf.whereAsync(filterMask);
filterCoords.print()
const newCoords = coords.gather(filterCoords.split(2, 1)[0].reshape([2]))
newCoords.print()
const matchIndexes = await newCoords.unstack().reduce(async (a, c) => {
const cropped = x.slice(await c.data(), part.shape)
const sameElements = (await tf.whereAsync(cropped.equal(part).asType('bool')))
if(tf.util.sizeFromShape(part.shape) * 2 === (await sameElements.data()).length) {
a.push(await c.data())
}
return a
}, [])
console.log('matching index', matchIndexes) // only [0, 0]
})()
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/#tensorflow/tfjs#latest"> </script>
</head>
<body>
</body>
</html>
To be more thorough, the convolutional filters is not enough to tell if there is a match. Actually a part of the tensor with the following values [[5, 6], [2, 1]] will also output 14. To make sure of outputting only the correct index, one can slice the input tensor at the given coordinates and check values bitwise if possible when the tensor processed are not big or just randomly some few elements.

tensorflow.js loss goes to infinity

I am trying to make a simple project to find coefficients of an equation using a tensorflow.js model. however, when ran, the loss approaches infinity and becomes NaN withing 4 or so iterations. I don't know why this is happening. Here is my code:
let xs = [];
let ys = [];
let aReal = Math.random();
let bReal = Math.random();
let cReal = Math.random();
let dReal = Math.random();
for (let i = -100; i < 100; i+=1) {
xs.push(i);
ys.push((aReal*Math.pow(i, 3) + bReal*Math.pow(i, 2) + cReal*i + dReal) + Math.random()*10-1);
}
const a = tf.variable(tf.scalar(Math.random()));
const b = tf.variable(tf.scalar(Math.random()));
const c = tf.variable(tf.scalar(Math.random()));
const d = tf.variable(tf.scalar(Math.random()));
function predict(x) {
return tf.tidy(() => {
return a.mul(x.pow(tf.scalar(3, 'int32')))
.add(b.mul(x.square()))
.add(c.mul(x))
.add(d);
});
}
function loss(predictions, labels) {
const meanSquareError = predictions.sub(labels).square().mean();
print(meanSquareError.dataSync());
return meanSquareError;
}
function train(xS, yS, numIterations) {
const learningRate = 0.1;
const optimizer = tf.train.sgd(learningRate);
console.log(xS.dataSync(), yS.dataSync());
for (let iter = 0; iter < numIterations; iter++) {
optimizer.minimize(() => {
const predYs = predict(xS);
return loss(predYs, yS);
});
}
}
train(tf.tensor(xs), tf.tensor(ys), 100);
let yPred = predict(tf.tensor(xs)).dataSync();
console.log(yPred);
let trace1 = {
x: xs,
y: ys,
mode: 'markers',
type: 'scatter'
};
let trace2 = {
x: xs,
y: yPred,
mode: 'lines',
};
console.log(aReal, bReal, cReal, dReal);
console.log(a.dataSync(), b.dataSync(), c.dataSync(), d.dataSync());
let graphData = [trace1, trace2];
Plotly.newPlot('graph', graphData);
Plotly is just a js library I'm using to plot the data.
Try lowering your learning rate. Once it's stable you can tweak it back up to speed training. If it's too high you'll get instability and NaNs
const learningRate = 0.0001;
You should try to normalize your input data for the prediction to work correctly. Otherwise the optimization becomes numerically unstable.
ys = [...];
// compute mean and stdev for ys!
normalized = (ys-ysmean)/(ysstd);
train(xs, normalized);
normed_pred = predict(xs);
pred = ysstd*normed_pred+ysmean;
In the tests I ran, your code works perfect on linear models y=ax+b; therefore my conclusion.
The loss depends on the values you start with, so if they are too big the loss may jump to the infinite and the prediction will return NaN. Try normalizing them so that they scale between 1 and -1. For instance when you train on MNIST, you divide all the values by 255, meaning that some white pixel [255, 255, 255] will become [1., 1., 1.].

Zed Graph with 3-X axis and 3-Y Axis

I m using zedGraph dll to save image of my graphs using points. Now I need to save a graphs with 1-X Axis and 3-Y axis. Also with 3-X axis and 1-Yaxis. Please help me out.
For the Y axis, this issue is fairly simple. Just add a sufficient number of YAxis objects to the GraphPane.YAxisList and associate the curves with respective axis by setting the YAxisIndex.
After adding all curves to the graph, update the scales of the Y axes by calling GraphPane.AxisChange().
Example:
var pane = zedGraphControl1.GraphPane;
pane.YAxisList.Clear();
var y1 = pane.AddYAxis("First");
var y2 = pane.AddYAxis("Secnd");
var y3 = pane.AddYAxis("Third");
var curve1 = new LineItem(null, new[] { 0.1, 0.5, 0.9 },
new[] { 0.8, 0.3, 0.1 }, Color.Blue, SymbolType.None) { YAxisIndex = y1 };
pane.CurveList.Add(curve1);
var curve2 = new LineItem(null, new[] { 0.1, 0.5, 0.9 },
new[] { -0.8, -0.3, -0.1 }, Color.Green, SymbolType.None) { YAxisIndex = y2 };
pane.CurveList.Add(curve2);
var curve3 = new LineItem(null, new[] { 0.1, 0.5, 0.9 },
new[] { -0.009, 0.001, 0.008 }, Color.Red, SymbolType.None) { YAxisIndex = y3 };
pane.CurveList.Add(curve3);
pane.AxisChange();
will produce the following result:
For X axes, you would be able to have 2 different X axes by utilizing both the XAxis and X2Axis properties of the graph pane, and setting the IsX2Axis property to true for the curve that should reference the second X axis.
I do not know of a solution for more than 2 X axes, though.