Skip to content
Snippets Groups Projects
Commit 2dc03d53 authored by Alexander Rose's avatar Alexander Rose
Browse files

added matplotlib derived and other color scales

parent c8684c17
No related branches found
No related tags found
No related merge requests found
...@@ -14,6 +14,10 @@ export namespace Color { ...@@ -14,6 +14,10 @@ export namespace Color {
return `rgb(${hexColor >> 16 & 255}, ${hexColor >> 8 & 255}, ${hexColor & 255})` return `rgb(${hexColor >> 16 & 255}, ${hexColor >> 8 & 255}, ${hexColor & 255})`
} }
export function toHexString(hexColor: Color) {
return '0x' + ('000000' + hexColor.toString(16)).slice(-6)
}
export function toRgb(hexColor: Color) { export function toRgb(hexColor: Color) {
return [ hexColor >> 16 & 255, hexColor >> 8 & 255, hexColor & 255 ] return [ hexColor >> 16 & 255, hexColor >> 8 & 255, hexColor & 255 ]
} }
...@@ -26,6 +30,10 @@ export namespace Color { ...@@ -26,6 +30,10 @@ export namespace Color {
return ((r << 16) | (g << 8) | b) as Color return ((r << 16) | (g << 8) | b) as Color
} }
export function fromNormalizedRgb(r: number, g: number, b: number ): Color {
return (((r * 255) << 16) | ((g * 255) << 8) | (b * 255)) as Color
}
/** Copies hex color to rgb array */ /** Copies hex color to rgb array */
export function toArray(hexColor: Color, array: Helpers.NumberArray, offset: number) { export function toArray(hexColor: Color, array: Helpers.NumberArray, offset: number) {
array[ offset ] = (hexColor >> 16 & 255) array[ offset ] = (hexColor >> 16 & 255)
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
import { Color } from './color' import { Color } from './color'
import { ColorBrewer } from './tables' import { ColorBrewer } from './tables'
import { ScaleLegend } from 'mol-view/theme/color'; import { ScaleLegend } from 'mol-view/theme/color';
import { defaults } from 'mol-util';
export interface ColorScale { export interface ColorScale {
/** Returns hex color for given value */ /** Returns hex color for given value */
...@@ -15,7 +16,9 @@ export interface ColorScale { ...@@ -15,7 +16,9 @@ export interface ColorScale {
colorToArray: (value: number, array: Helpers.NumberArray, offset: number) => void colorToArray: (value: number, array: Helpers.NumberArray, offset: number) => void
/** Copies normalized (0 to 1) hex color to rgb array */ /** Copies normalized (0 to 1) hex color to rgb array */
normalizedColorToArray: (value: number, array: Helpers.NumberArray, offset: number) => void normalizedColorToArray: (value: number, array: Helpers.NumberArray, offset: number) => void
/** */ /** */
setDomain: (min: number, max: number) => void
/** Legend */
readonly legend: ScaleLegend readonly legend: ScaleLegend
} }
...@@ -23,16 +26,27 @@ export const DefaultColorScale = { ...@@ -23,16 +26,27 @@ export const DefaultColorScale = {
domain: [0, 1], domain: [0, 1],
reverse: false, reverse: false,
colors: ColorBrewer.RdYlBu, colors: ColorBrewer.RdYlBu,
minLabel: '' as string | undefined,
maxLabel: '' as string | undefined,
} }
export type ColorScaleProps = Partial<typeof DefaultColorScale> export type ColorScaleProps = Partial<typeof DefaultColorScale>
export namespace ColorScale { export namespace ColorScale {
export function create(props: ColorScaleProps): ColorScale { export function create(props: ColorScaleProps): ColorScale {
const { domain, reverse, colors: _colors } = { ...DefaultColorScale, ...props } const { domain, reverse, colors: _colors } = { ...DefaultColorScale, ...props }
const [ min, max ] = domain
const colors = reverse ? _colors.slice().reverse() : _colors const colors = reverse ? _colors.slice().reverse() : _colors
const count1 = colors.length - 1 const count1 = colors.length - 1
const diff = (max - min) || 1
let diff = 0, min = 0, max = 0
function setDomain(_min: number, _max: number) {
min = _min
max = _max
diff = (max - min) || 1
}
setDomain(domain[0], domain[1])
const minLabel = defaults(props.minLabel, min.toString())
const maxLabel = defaults(props.maxLabel, max.toString())
function color(value: number) { function color(value: number) {
const t = Math.min(colors.length - 1, Math.max(0, ((value - min) / diff) * count1)) const t = Math.min(colors.length - 1, Math.max(0, ((value - min) / diff) * count1))
...@@ -49,7 +63,8 @@ export namespace ColorScale { ...@@ -49,7 +63,8 @@ export namespace ColorScale {
normalizedColorToArray: (value: number, array: Helpers.NumberArray, offset: number) => { normalizedColorToArray: (value: number, array: Helpers.NumberArray, offset: number) => {
Color.toArrayNormalized(color(value), array, offset) Color.toArrayNormalized(color(value), array, offset)
}, },
get legend() { return ScaleLegend(min, max, colors) } setDomain,
get legend() { return ScaleLegend(minLabel, maxLabel, colors) }
} }
} }
} }
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { ColorMap, ColorTable } from './color'; import { ColorMap, ColorTable, Color } from './color';
/** /**
* Brewer Color Lists * Brewer Color Lists
...@@ -56,6 +56,44 @@ export const ColorBrewer = ColorTable({ ...@@ -56,6 +56,44 @@ export const ColorBrewer = ColorTable({
Pastel1: [0xfbb4ae, 0xb3cde3, 0xccebc5, 0xdecbe4, 0xfed9a6, 0xffffcc, 0xe5d8bd, 0xfddaec, 0xf2f2f2] Pastel1: [0xfbb4ae, 0xb3cde3, 0xccebc5, 0xdecbe4, 0xfed9a6, 0xffffcc, 0xe5d8bd, 0xfddaec, 0xf2f2f2]
}) })
/**
* Matplotlib colormaps, including various perceptually uniform shades, see https://bids.github.io/colormap/
*/
export const ColorMatplotlib = ColorTable({
/** perceptually uniform shades of black-red-white */
magma: [
0x420f74, 0x4a1079, 0x52127c, 0x5a157e, 0x61187f, 0x691c80, 0x711f81, 0x792281, 0x812581, 0x892881, 0x912a80, 0x992d7f, 0xa12f7e, 0xa9327c, 0xb1357a, 0xb93778, 0xc23a75, 0xca3e72, 0xd1426e, 0xd9466a, 0xe04b66, 0xe65162, 0xec585f, 0xf0605d, 0xf4685b, 0xf7715b, 0xf97b5d, 0xfb8460, 0xfc8e63, 0xfd9768, 0xfda16e, 0xfeaa74, 0xfeb37b, 0xfebc82, 0xfec689, 0xfdcf92, 0xfdd89a, 0xfde1a3, 0xfceaac, 0xfcf3b5, 0xfbfcbf
],
/** perceptually uniform shades of black-red-yellow */
inferno: [
0x480b6a, 0x500d6c, 0x58106d, 0x60136e, 0x68166e, 0x70196e, 0x781c6d, 0x801f6b, 0x88216a, 0x902468, 0x982765, 0xa02a62, 0xa72d5f, 0xaf315b, 0xb73456, 0xbe3852, 0xc53d4d, 0xcc4148, 0xd24742, 0xd94d3d, 0xde5337, 0xe45a31, 0xe8612b, 0xed6825, 0xf0701e, 0xf37918, 0xf68111, 0xf88a0b, 0xfa9306, 0xfb9d06, 0xfba60b, 0xfbb014, 0xfbb91e, 0xf9c32a, 0xf8cd37, 0xf5d745, 0xf3e056, 0xf1e968, 0xf1f27d, 0xf5f891, 0xfcfea4
],
/** perceptually uniform shades of blue-red-yellow */
plasma: [
0x1b068c, 0x250591, 0x2f0495, 0x380499, 0x40039c, 0x49029f, 0x5101a2, 0x5901a4, 0x6100a6, 0x6800a7, 0x7000a8, 0x7801a8, 0x7f03a7, 0x8607a6, 0x8e0ca4, 0x9511a1, 0x9b179e, 0xa21c9a, 0xa82296, 0xae2791, 0xb42d8d, 0xb93388, 0xbe3883, 0xc33e7f, 0xc8447a, 0xcd4975, 0xd14f71, 0xd6556d, 0xda5a68, 0xde6064, 0xe26660, 0xe56c5b, 0xe97257, 0xec7853, 0xef7e4e, 0xf2854a, 0xf58b46, 0xf79241, 0xf9993d, 0xfaa039, 0xfca735, 0xfdaf31, 0xfdb62d, 0xfdbe29, 0xfdc626, 0xfcce25, 0xfad624, 0xf8df24, 0xf5e726, 0xf2f026, 0xeff821
],
/** perceptually uniform shades of blue-green-yellow */
viridis: [
0x45085b, 0x470f62, 0x471669, 0x481d6f, 0x482374, 0x472a79, 0x46307d, 0x453681, 0x433c84, 0x414286, 0x3e4888, 0x3c4d8a, 0x3a538b, 0x37588c, 0x355d8c, 0x32628d, 0x30678d, 0x2e6c8e, 0x2c718e, 0x2a768e, 0x287a8e, 0x267f8e, 0x24848d, 0x23898d, 0x218d8c, 0x1f928c, 0x1e978a, 0x1e9b89, 0x1ea087, 0x20a585, 0x23a982, 0x28ae7f, 0x2eb27c, 0x35b778, 0x3dbb74, 0x45bf6f, 0x4fc369, 0x59c764, 0x64cb5d, 0x70ce56, 0x7cd24f, 0x88d547, 0x95d73f, 0xa2da37, 0xafdc2e, 0xbdde26, 0xcae01e, 0xd7e219, 0xe4e318, 0xf1e51c, 0xfde724
],
/**
* perceptually uniform shades of blue-green-yellow,
* should look effectively identical to colorblind and non-colorblind users
*/
cividis: [
0x002c67, 0x003070, 0x083370, 0x16366f, 0x1f3a6e, 0x273d6d, 0x2e416c, 0x34446c, 0x39486c, 0x3f4b6b, 0x444f6b, 0x49526b, 0x4e566c, 0x52596c, 0x575d6d, 0x5b606e, 0x60646e, 0x64676f, 0x686b71, 0x6d6e72, 0x717273, 0x757575, 0x797977, 0x7e7d78, 0x838078, 0x878478, 0x8c8878, 0x918c77, 0x968f77, 0x9b9376, 0xa09775, 0xa59b73, 0xaa9f72, 0xafa370, 0xb4a76f, 0xb9ab6d, 0xbeb06a, 0xc4b468, 0xc9b865, 0xcebc62, 0xd4c15e, 0xd9c55a, 0xdfca56, 0xe4ce51, 0xead34c, 0xefd846, 0xf5dc3f, 0xfbe136, 0xfde737
],
/** perceptually uniform shades of white-blue-black-red-white, cyclic */
twilight: [
0xdfd9e1, 0xd8d7dd, 0xced3d8, 0xc2cdd3, 0xb4c7ce, 0xa7c0ca, 0x9ab8c7, 0x8eb0c5, 0x83a8c3, 0x7a9fc2, 0x7297c0, 0x6b8ebf, 0x6684bd, 0x637bbb, 0x6171b9, 0x5f67b6, 0x5e5cb2, 0x5e51ad, 0x5d46a7, 0x5c3c9f, 0x5b3196, 0x58278b, 0x531e7d, 0x4d176e, 0x46135f, 0x3e1151, 0x381045, 0x32113b, 0x301336, 0x361138, 0x3e113c, 0x471240, 0x521445, 0x5e1749, 0x6a1a4d, 0x761e4f, 0x812350, 0x8b2a50, 0x95324f, 0x9d3a4f, 0xa5434f, 0xac4d50, 0xb25752, 0xb86155, 0xbc6c59, 0xc0775f, 0xc48267, 0xc78d70, 0xc9987b, 0xcca389, 0xceae97, 0xd2b8a6, 0xd6c1b5, 0xdacac4, 0xddd1d1, 0xe0d6db, 0xe1d8e1
]
})
export const ColorOther = ColorTable({
rainbow: [ 0x3361E1, 0x35A845, 0xF9FF00, 0xEC8711, 0xBF2222 ],
rwb: [ 0xBF2222, 0xFFFFFF, 0x3361E1 ],
})
/** X11 color names http://www.w3.org/TR/css3-color/#svg-color */ /** X11 color names http://www.w3.org/TR/css3-color/#svg-color */
export const ColorNames = ColorMap({ export const ColorNames = ColorMap({
aliceblue: 0xf0f8ff, aliceblue: 0xf0f8ff,
......
...@@ -24,12 +24,12 @@ export type LocationColor = (location: Location, isSecondary: boolean) => Color ...@@ -24,12 +24,12 @@ export type LocationColor = (location: Location, isSecondary: boolean) => Color
export interface ScaleLegend { export interface ScaleLegend {
kind: 'scale-legend' kind: 'scale-legend'
min: number, minLabel: string,
max: number, maxLabel: string,
colors: Color[] colors: Color[]
} }
export function ScaleLegend(min: number, max: number, colors: Color[]): ScaleLegend { export function ScaleLegend(minLabel: string, maxLabel: string, colors: Color[]): ScaleLegend {
return { kind: 'scale-legend', min, max, colors } return { kind: 'scale-legend', minLabel, maxLabel, colors }
} }
export interface TableLegend { export interface TableLegend {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment