Skip to content

Commit

Permalink
Fix frequency colors for ordinal scales
Browse files Browse the repository at this point in the history
The underlying bug was a type-inconsistency whereby color-by values
can be numeric however the matrix was stored as an Object (where keys
are always stringified) and so `matrix[numeric_colorBy_value]=undefined`.
Switching to a Map() allows typed keys and fixes this bug.

Closes #843
  • Loading branch information
jameshadfield committed Oct 20, 2022
1 parent e8e1e74 commit d324887
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 13 deletions.
6 changes: 3 additions & 3 deletions src/components/frequencies/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,10 @@ const turnMatrixIntoSeries = (categories, nPivots, matrix) => {
const x = [];
for (let j = 0; j < nPivots; j++) {
if (i === 0) {
x.push([0, matrix[categories[i]][j]]);
x.push([0, matrix.get(categories[i])[j]]);
} else {
const prevY1 = series[i - 1][j][1];
x.push([prevY1, matrix[categories[i]][j] + prevY1]);
x.push([prevY1, matrix.get(categories[i])[j] + prevY1]);
}
}
series.push(x);
Expand Down Expand Up @@ -252,7 +252,7 @@ const calcMaxYValue = (series) => {
};

export const processMatrix = ({matrix, pivots, colorScale}) => {
const categories = getOrderedCategories(Object.keys(matrix), colorScale);
const categories = getOrderedCategories(Array.from(matrix.keys()), colorScale);
const series = turnMatrixIntoSeries(categories, pivots.length, matrix);
const maxY = calcMaxYValue(series);
return {categories, series, maxY};
Expand Down
22 changes: 12 additions & 10 deletions src/util/processFrequencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,13 @@ export const computeMatrixFromRawData = (
const categories = colorScale.legendValues.filter((d) => d !== undefined);
categories.push(unassigned_label); /* for tips without a colorBy */
const isGenotype = isColorByGenotype(colorBy);
const matrix = {}; /* SHAPE: rows: categories (colorBys), columns: pivots */
/* Matrix shape: first level (keys of Map) are values of the current colorBy. Type is preserved (hence the use of a Map())
second level (elements of array) are the pivots & their frequency value.
matrix.get('22L')[3] is the (3+1)th pivot for the color-by value 21L */
const matrix = new Map();
const pivotsLen = pivots.length;
categories.forEach((x) => {
matrix[x] = new Array(pivotsLen).fill(0);
matrix.set(x, new Array(pivotsLen).fill(0));
});
// let debugTipsSeen = 0;
const debugPivotTotals = new Array(pivotsLen).fill(0);
Expand All @@ -79,7 +82,7 @@ export const computeMatrixFromRawData = (
unassigned_label;
// if (category === unassigned_label) return;
for (let i = 0; i < pivotsLen; i++) {
matrix[category][i] += d.values[i];
matrix.get(category)[i] += d.values[i];
debugPivotTotals[i] += d.values[i];
// if (i === pivotsLen - 1 && d.values[i] !== 0) {
// console.log("Pivot", frequencies.pivots[i], "strain", tree.nodes[d.idx].strain, "(clade #", tree.nodes[d.idx].strain, ") carried frequency of", d.values[i]);
Expand All @@ -90,21 +93,20 @@ export const computeMatrixFromRawData = (

if (normalizeFrequencies) {
const minVal = 1e-7;
Object.keys(matrix).forEach((cat) => {
for (const [cat] of matrix) {
debugPivotTotals.forEach((norm, i) => {
if (norm > minVal) {
matrix[cat][i] /= norm;
matrix.get(cat)[i] /= norm;
} else {
matrix[cat][i] = 0.0;
matrix.get(cat)[i] = 0.0;
}
});
});
}
}

if (matrix[unassigned_label].reduce((a, b) => a + b, 0) === 0) {
delete matrix[unassigned_label];
if (matrix.get(unassigned_label).reduce((a, b) => a + b, 0) === 0) {
matrix.delete(unassigned_label);
}

return matrix;
};

Expand Down

0 comments on commit d324887

Please sign in to comment.