Color map for J coupling
This color map was designed for J-graphs and other color-coded representation of NMR J(H,H) ranging from 0 to 20 Hz.
It was chosen order to provide a large color contrast for values that are particularily significant (small, about 7.0 and about 12 Hz).
J | Black background | White background |
---|---|---|
Hz | RGB (0-1) | RGB (0-1) |
0 | (0 1 1) | (0 1 1) |
2 | (0 1 0) | (0 1 0) |
4 | (1 1 0) | (0.8 0.8 0) |
6 | (1 0.5 0) | (0.9 0.4 0) |
8 | (1 0 0) | (1 0 0) |
10 | (1 0 0.5) | (1 0 0.5) |
12 | (1 0 1) | (1 0 1) |
14 | (0.5 0 0.9) | (0.5 0 1) |
16 | (0.2 0.2 1) | (0 0 1) |
18 | (0.4 0.4 0.5) | (0 0 0.5) |
20 | (1 1 1) | (0 0 0) |
Convert J value into (R, G, B) values (0 - 1). In C++
// input
const double Jcoupling = 7.1 ; // Hz
// Color maps. First color for 0 Hz, second color for 2 Hz, etc. up to 20 Hz
const double colormapWhiteBackground[] = {0, 1, 1, 0, 1, 0, 0.8, 0.8, 0, 0.9, 0.4, 0, 1, 0, 0, 1, 0, 0.5, 1, 0, 1, 0.5, 0, 1, 0, 0, 1, 0, 0, 0.5, 0, 0, 0,}; // for white background
const double colormap[] = {0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0.5, 0, 1, 0, 0, 1, 0, 0.5, 1, 0, 1, 0.5, 0, 0.9, 0.2, 0.2, 1, 0.4, 0.4, 0.5, 1, 1, 1,}; // for black background
const double JcouplingAbs = abs(Jcoupling) ; // Hz
int baseColorInt = floor(JcouplingAbs / 2.0); // -20 - 20.0 -> 0 - 9
if (baseColorInt > 9) baseColorInt = 9; // baseColorInt 0 - 9
float adjust = (JcouplingAbs - 2 * baseColorInt) / 2.0; // normalized diff (0-1) for 2 Hz
if (adjust > 1.0) adjust = 1.0; // adjust 0 - 1.0
const int baseColorIndex = 3 * baseColorInt; // 3 because RGB
// Output
double colormap[] = {0, 0, 0};
// the loop is language dependent, lets drop it...
curColor[0] = colormap[baseColorIndex + 0] + adjust * (colormap[baseColorIndex + 3 + 0] - colormap[baseColorIndex + 0]);
curColor[1] = colormap[baseColorIndex + 1] + adjust * (colormap[baseColorIndex + 3 + 1] - colormap[baseColorIndex + 1]);
curColor[2] = colormap[baseColorIndex + 2] + adjust * (colormap[baseColorIndex + 3 + 2] - colormap[baseColorIndex + 2]);
const bool negExpVal = (Jcoupling < 0.0); // used to change line type for negative values.
Javascript version
export function getJColor(Jcoupling, darkmode) {
// https://nmredatainitiative.github.io/color-map-J-coupling/
// input
// Color maps. First color for 0 Hz, second color for 2 Hz, etc. up to 20 Hz
var colormap = [0, 1, 1, 0, 1, 0, 0.8, 0.8, 0, 0.9, 0.4, 0, 1, 0, 0, 1, 0, 0.5, 1, 0, 1, 0.5, 0, 1, 0, 0, 1, 0, 0, 0.5, 0, 0, 0]; // for white background
if (darkmode) {
colormap = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0.5, 0, 1, 0, 0, 1, 0, 0.5, 1, 0, 1, 0.5, 0, 0.9, 0.2, 0.2, 1, 0.4, 0.4, 0.5, 1, 1, 1]; // for black background
}
const JcouplingAbs = Math.abs(Jcoupling); // Hz
var baseColorInt = Math.floor(JcouplingAbs / 2.0); // -20 - 20.0 -> 0 - 9
if (baseColorInt > 9) baseColorInt = 9; // baseColorInt 0 - 9
var adjust = +(JcouplingAbs - 2.0 * baseColorInt) / 2.0; // normalized diff (0-1) for 2 Hz
if (adjust > 1.0) adjust = 1.0; // adjust 0 - 1.0
const baseColorIndex = 3 * baseColorInt; // 3 because RGB
// the loop is language dependent, lets drop it...
const r = Math.floor(+255.0 * (colormap[baseColorIndex + 0] + adjust * (colormap[baseColorIndex + 3 + 0] - colormap[baseColorIndex + 0])));
const g = Math.floor(+255.0 * (colormap[baseColorIndex + 1] + adjust * (colormap[baseColorIndex + 3 + 1] - colormap[baseColorIndex + 1])));
const b = Math.floor(+255.0 * (colormap[baseColorIndex + 2] + adjust * (colormap[baseColorIndex + 3 + 2] - colormap[baseColorIndex + 2])));
//const negExpVal = (Jcoupling < 0.0); // used to change line type for negative values.
return (["rgb(", r, ",", g, ",", b, ")"].join(""));
}
Javascript version
export function getJColor(Jcoupling, darkmode) {
// https://nmredatainitiative.github.io/color-map-J-coupling/
// input
// Color maps. First color for 0 Hz, second color for 2 Hz, etc. up to 20 Hz
var colormap = [0, 1, 1, 0, 1, 0, 0.8, 0.8, 0, 0.9, 0.4, 0, 1, 0, 0, 1, 0, 0.5, 1, 0, 1, 0.5, 0, 1, 0, 0, 1, 0, 0, 0.5, 0, 0, 0]; // for white background
if (darkmode) {
colormap = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0.5, 0, 1, 0, 0, 1, 0, 0.5, 1, 0, 1, 0.5, 0, 0.9, 0.2, 0.2, 1, 0.4, 0.4, 0.5, 1, 1, 1]; // for black background
}
const JcouplingAbs = Math.abs(Jcoupling); // Hz
var baseColorInt = Math.floor(JcouplingAbs / 2.0); // -20 - 20.0 -> 0 - 9
if (baseColorInt > 9) baseColorInt = 9; // baseColorInt 0 - 9
var adjust = +(JcouplingAbs - 2.0 * baseColorInt) / 2.0; // normalized diff (0-1) for 2 Hz
if (adjust > 1.0) adjust = 1.0; // adjust 0 - 1.0
const baseColorIndex = 3 * baseColorInt; // 3 because RGB
// the loop is language dependent, lets drop it...
const r = Math.floor(+255.0 * (colormap[baseColorIndex + 0] + adjust * (colormap[baseColorIndex + 3 + 0] - colormap[baseColorIndex + 0])));
const g = Math.floor(+255.0 * (colormap[baseColorIndex + 1] + adjust * (colormap[baseColorIndex + 3 + 1] - colormap[baseColorIndex + 1])));
const b = Math.floor(+255.0 * (colormap[baseColorIndex + 2] + adjust * (colormap[baseColorIndex + 3 + 2] - colormap[baseColorIndex + 2])));
//const negExpVal = (Jcoupling < 0.0); // used to change line type for negative values.
return (["rgb(", r, ",", g, ",", b, ")"].join(""));
}
Please make pull requests or raise issue to send us your code in other languages!