I have an application monitoring a number of data points and I'm performing colouring based on the linear percentage fading between green, yellow and red. This however doesn't accurately visualise the problem as the higher the number the exponentially worse it is. The range is 0 -> 30000, how can I generate what I think would be termed a logarithmic percentage value rather than a linear one?
4 Answers
I assume by "logarithmic percentage" you want to map your data to the range [0, 100] on a logarithmic basis. You can try something like this:
double Scale(int val)
{
if (val <= 1)
return 0; // log is undefined for 0, log(1) = 0
return 100 * Math.Log(val) / Math.Log(30000);
}

- 6,187
- 3
- 28
- 55
-
This is the correct answer if you want to plot exponentially growing values. – besimple Dec 21 '15 at 19:50
Use a function of the following form.
f(x) = s bx / 30000 + t
We know that 0 should map to 0% and 30000 should map to 100%.
f(0) = 0
f(30000) = 100
These imply the following system of equations.
s + t = 0
s b + t = 100
The solution (with respect to b) is the following.
s = 100 / (b - 1)
t = -100 / (b - 1)
Pick a particular b > 1 value (say b = 10). Then you get the following solution.
s = 100 / 9
t = -100 / 9
That is, the function f(x) is the following.
f(x) = (100 10x / 30000 - 100) / 9
You can see a plot of this function here: Wolfram Alpha
In C# this will look like the following.
double x = ...;
double b = 10.0;
double s = 100.0 / (b - 1);
double t = -100.0 / (b - 1);
double f = s * Math.Pow(b, x / 30000.0) + t;

- 75,459
- 18
- 120
- 173
-
Surely this graph is exponential instead of logarithmic. i.e. it grows slowly and then explodes. As opposed to exploding and then growing slowly to its peak. – Ian Warburton May 11 '15 at 15:29
-
@IanWarburton I'm missing the point? Where in the answer do I say it's logarithmic? It's clearly exponential. :) – Timothy Shields May 11 '15 at 15:33
-
@IanWarburton Oh - now I see. Why does the code use `Math.Log` instead of `Math.Pow`? The definition of `f` at the start of the answer uses exponentation. Good catch. – Timothy Shields May 11 '15 at 15:35
Improving on bmm6o's answer:
public static double Scale(long value, long maxInputValue, long maxOutputValue)
{
if (value <= 1)
return 0; // log is undefined for 0, log(1) = 0
return maxOutputValue * Math.Log(value) / Math.Log(maxInputValue);
}
if you're looking for something between linear and logarithmic, the following might help:
public static double Scale(long value, long maxInputValue, long maxOutputValue, double scaleFactor)
{
if (value <= 1)
return 0; // log is undefined for 0, log(1) = 0
return maxOutputValue * Math.Pow(Math.Log(value), scaleFactor) / Math.Pow(Math.Log(maxInputValue), scaleFactor);
}

- 1,429
- 14
- 14
Use Math.Log(double)
(or Math.Log(double, double)
if you want to play around with the base) to get the logarithm of your value, which you can than map to a color value.

- 28,507
- 14
- 48
- 67