All Apps and Add-ons

Is it possible to map value to color/color code using a bilinear color gradient for visualization?

Olli1919
Path Finder

(Disclaimer: May be a little sympathetic nuts. Meaning you do necessarily need to be sane to enjoy this question/answer)

Many custom visualizations can work with a colorcode in the event data to further enrich a chart.
Is it possible to map a numerical value to a color / colorcode? E.g. 42.4 -> #FFA500
Furthermore, is it possible to map a value range to a color range? E.g. 0.0-1.0 -> green-red?

0 Karma
1 Solution

Olli1919
Path Finder

A nice usage scenario for chart annotation (e.g. heatmap) is to merge two values (e.g. local riskscore, global riskscore) into a single color. Of course the same could be achieved in coming up with an overall score first and mapping this into a colorcode.

But since splunk can do, let's take the more colorful approach of "mapping two values into a 2D color space" ("Bilinear Interpolate Color Gradient").

As referenced in slide 26 of conf19's: SEC1374 - Augment Your Security Monitoring Use Cases with Splunk's Machine Learning Toolkit (@time 41:04)
Colorize Graph using two riskscores
bilinearInterpolateColorGradient(inputVal1, inputVal2, colorspaceCol00, colorspaceColX0, colorspaceCol0Y, colorspaceColXY, "outcolor")

Goal:
- Input two values in the range of 0..1
- Map into a 2D colorspace defined by the four colorcodes in the corners
- Output a single colorcode in the format "#AABBCC"

Result:
The two input values will get mapped into a 2D colorspace like this one:
2DColorspace at HarmonicCode: harmoniccode.blogspot.com
For a great explanation, refer to this article:
Bilinear color interpolation at HarmonicCode: harmoniccode.blogspot.com

Code: (4 Macros)

bilinearInterpolateColorGradient(7)

`comment("
    Maps two values into a color space with four colors.
    Outputs a final color, smoothly interpolated between these four color, 
    on basis of the two input values.
    https://harmoniccode.blogspot.com/2011/04/bilinear-color-interpolation.html
    x: Input value 1 (x axis in color space. left->right)
    y: Input value 2 (y axis in color space. bottom->top)    
    col00: color in the bottom left corner of the color space.
    colX0: color in the bottom right corner of the color space.
    col0Y: color in the top left corner of the color space.
    colXY: color in the top right corner of the color space.
    outcolorfieldname: name of field in which the final color is written.
")`

| eval _x = $x$
| eval _y = $y$
| eval _col00 = $col00$
| eval _colX0 = $colX0$
| eval _col0Y = $col0Y$
| eval _colXY = $colXY$
`interpolateColor(_col00, _colX0, _x, "_outcolorB")`
`interpolateColor(_col0Y, _colXY, _x, "_outcolorT")`
`interpolateColor(_outcolorB, _outcolorT, _y, "_outcolor")`
| eval $outcolorfieldname$ = _outcolor

interpolateColor(4)

| eval _col1 = $col1$
| eval _col2 = $col2$
| eval _lerpt = $lerpt$
| eval _outcolor = "#ZZZZZZ"

| eval _lerpt = if(_lerpt > 1, 1.0, _lerpt)
| eval _lerpt = if(_lerpt < 0.0, 0.0, _lerpt)

`splitColorIntoComponents(_col1, "_col1r", "_col1g", "_col1b")`
`splitColorIntoComponents(_col2, "_col2r", "_col2g", "_col2b")`
| eval _deltaRed = _col2r - _col1r, _deltaGreen = _col2g - _col1g, _deltaBlue = _col2b - _col1b
| eval _outRed = _col1r + _lerpt * _deltaRed, _outGreen = _col1g + _lerpt * _deltaGreen, _outBlue = _col1b + _lerpt * _deltaBlue
`genColorFromComponents(_outRed, _outGreen, _outBlue, "_outcolor")`

| eval $outcolorfieldname$ = _outcolor

splitColorIntoComponents(4)

| eval _color = $color$
| rex field=_color "^#(?<_red>[0-9a-zA-Z]{2,2})(?<_green>[0-9a-zA-Z]{2,2})(?<_blue>[0-9a-zA-Z]{2,2})$"
| eval _red = tonumber(_red, 16), _green = tonumber(_green, 16), _blue = tonumber(_blue, 16)
| eval $oufieldname_red$ = _red
| eval $oufieldname_green$ = _green
| eval $oufieldname_blue$ = _blue

genColorFromComponents(4)

| eval _red = $red$
| eval _green = $green$
| eval _blue = $blue$
| eval _outcolor = "#" + upper(printf("%02x", _red)) + upper(printf("%02x", _green)) + upper(printf("%02x", _blue))
| eval $outcolorfieldname$ = _outcolor

Testbed / Usage example

| makeresults count=484
| eval count = 22
| streamstats count as id
| eval id = id - 1
| eval x = floor(id / count) / count, y = (id % count) / count, z = 0

| eval col00 = "#00AA00"
| eval colX0 = "#FFA500"
| eval col0Y = "#FFFF00"
| eval colXY = "#FF0000"

`bilinearInterpolateColorGradient(x, y, col00, colX0, col0Y, colXY, "outcolor")`
| eval clusterId=outcolor, clusterColor=outcolor, z=0
| table clusterId, x, y, z, clusterColor

**-> Render the generated events into MLTK's 3D Scatterplot**

View solution in original post

Olli1919
Path Finder

A nice usage scenario for chart annotation (e.g. heatmap) is to merge two values (e.g. local riskscore, global riskscore) into a single color. Of course the same could be achieved in coming up with an overall score first and mapping this into a colorcode.

But since splunk can do, let's take the more colorful approach of "mapping two values into a 2D color space" ("Bilinear Interpolate Color Gradient").

As referenced in slide 26 of conf19's: SEC1374 - Augment Your Security Monitoring Use Cases with Splunk's Machine Learning Toolkit (@time 41:04)
Colorize Graph using two riskscores
bilinearInterpolateColorGradient(inputVal1, inputVal2, colorspaceCol00, colorspaceColX0, colorspaceCol0Y, colorspaceColXY, "outcolor")

Goal:
- Input two values in the range of 0..1
- Map into a 2D colorspace defined by the four colorcodes in the corners
- Output a single colorcode in the format "#AABBCC"

Result:
The two input values will get mapped into a 2D colorspace like this one:
2DColorspace at HarmonicCode: harmoniccode.blogspot.com
For a great explanation, refer to this article:
Bilinear color interpolation at HarmonicCode: harmoniccode.blogspot.com

Code: (4 Macros)

bilinearInterpolateColorGradient(7)

`comment("
    Maps two values into a color space with four colors.
    Outputs a final color, smoothly interpolated between these four color, 
    on basis of the two input values.
    https://harmoniccode.blogspot.com/2011/04/bilinear-color-interpolation.html
    x: Input value 1 (x axis in color space. left->right)
    y: Input value 2 (y axis in color space. bottom->top)    
    col00: color in the bottom left corner of the color space.
    colX0: color in the bottom right corner of the color space.
    col0Y: color in the top left corner of the color space.
    colXY: color in the top right corner of the color space.
    outcolorfieldname: name of field in which the final color is written.
")`

| eval _x = $x$
| eval _y = $y$
| eval _col00 = $col00$
| eval _colX0 = $colX0$
| eval _col0Y = $col0Y$
| eval _colXY = $colXY$
`interpolateColor(_col00, _colX0, _x, "_outcolorB")`
`interpolateColor(_col0Y, _colXY, _x, "_outcolorT")`
`interpolateColor(_outcolorB, _outcolorT, _y, "_outcolor")`
| eval $outcolorfieldname$ = _outcolor

interpolateColor(4)

| eval _col1 = $col1$
| eval _col2 = $col2$
| eval _lerpt = $lerpt$
| eval _outcolor = "#ZZZZZZ"

| eval _lerpt = if(_lerpt > 1, 1.0, _lerpt)
| eval _lerpt = if(_lerpt < 0.0, 0.0, _lerpt)

`splitColorIntoComponents(_col1, "_col1r", "_col1g", "_col1b")`
`splitColorIntoComponents(_col2, "_col2r", "_col2g", "_col2b")`
| eval _deltaRed = _col2r - _col1r, _deltaGreen = _col2g - _col1g, _deltaBlue = _col2b - _col1b
| eval _outRed = _col1r + _lerpt * _deltaRed, _outGreen = _col1g + _lerpt * _deltaGreen, _outBlue = _col1b + _lerpt * _deltaBlue
`genColorFromComponents(_outRed, _outGreen, _outBlue, "_outcolor")`

| eval $outcolorfieldname$ = _outcolor

splitColorIntoComponents(4)

| eval _color = $color$
| rex field=_color "^#(?<_red>[0-9a-zA-Z]{2,2})(?<_green>[0-9a-zA-Z]{2,2})(?<_blue>[0-9a-zA-Z]{2,2})$"
| eval _red = tonumber(_red, 16), _green = tonumber(_green, 16), _blue = tonumber(_blue, 16)
| eval $oufieldname_red$ = _red
| eval $oufieldname_green$ = _green
| eval $oufieldname_blue$ = _blue

genColorFromComponents(4)

| eval _red = $red$
| eval _green = $green$
| eval _blue = $blue$
| eval _outcolor = "#" + upper(printf("%02x", _red)) + upper(printf("%02x", _green)) + upper(printf("%02x", _blue))
| eval $outcolorfieldname$ = _outcolor

Testbed / Usage example

| makeresults count=484
| eval count = 22
| streamstats count as id
| eval id = id - 1
| eval x = floor(id / count) / count, y = (id % count) / count, z = 0

| eval col00 = "#00AA00"
| eval colX0 = "#FFA500"
| eval col0Y = "#FFFF00"
| eval colXY = "#FF0000"

`bilinearInterpolateColorGradient(x, y, col00, colX0, col0Y, colXY, "outcolor")`
| eval clusterId=outcolor, clusterColor=outcolor, z=0
| table clusterId, x, y, z, clusterColor

**-> Render the generated events into MLTK's 3D Scatterplot**

View solution in original post

Register for .conf21 Now! Go Vegas or Go Virtual!

How will you .conf21? You decide! Go in-person in Las Vegas, 10/18-10/21, or go online with .conf21 Virtual, 10/19-10/20.