I have the following example set of data spanning an [x,y]
domain:
test=[2.58,2.2, 0.00023, 0.000163, 0.000123, 0.000164, 0.00022, 2.18, 2.56,2.56;
2.46,2.17, 0.00021, 0.000150, 0.000119, 0.000141, 0.00020, 2.16, 2.43, 2.56;
2.35,2.14, 0.00019, 0.000143, 0.000101, 0.000136, 0.00018, 2.14, 2.36,2.56;
2.23,2.12, 0.000184, 0.000138, 0.000095, 0.000124, 0.000166, 2.12, 2.24,2.56;
2.2,2.11, 0.000177, 0.000141, 0.00009, 0.000101, 0.000156, 2.09, 2.18, 2.56;
2.25,2.1, 0.000176, 0.000168, 0.00008, 0.000095, 0.000164, 2.08, 2.26, 2.56;
2.32,2.13, 0.000183, 0.000178, 0.000086, 0.000104, 0.000177, 2.11, 2.35,2.56;
2.44, 2.15, 0.00019, 0.000191, 0.000099, 0.000112, 0.000189, 2.13, 2.44,2.56;
2.56, 2.17,0.00021, 0.000199, 0.000101, 0.000132, 0.000199, 2.15, 2.52,2.56;
2.59, 2.19, 0.00022, 0.000209, 0.000118, 0.000144, 0.00021, 2.19,2.55, 2.56]
As you can see, the data at the edges are much higher than the data in the middle, i.e. there are two different scales. Using Matlab surface plot (surf(test)
) I can choose to focus on the edges, by setting the colormap max on 2.6
and I get:
Focus on the edges.
This shows local differences in the edges fairly well, but no differences in the middle part are visible.
Alternatively I can focus on the middle by setting the max at 0.00025
and I get:
Focus on the middle,
which shows the local differences in the middle, but not at the edges.
I would really like to combine both. I played around with the colormapeditor a lot, but did not find a satisfying solution yet.
Ideally I would divide my colorbar into two regions, one blue region ranging from 0
to 0.00023
(maximal value of the middle region) and the second, yellow region, ranging from 0.00023
to 2.59
(maximal value of the edge region).
Alternatively some overlay of both pictures would be possible (in 2D fairly easy, but I also would like to do this in 3D), but I prefer to solve it with a custom colorbar.
Does anyone know how to do this?
The issue you have come across is that of high dynamic range data. There is no way to solve this in general.
From the perspective of High Dynamic Range (HDR) photography, what you are asking to do has a name: Tonemapping. There is no simple answer on how to solve this. Taking the Logarithm of your data as Amos suggested, is a great first step. This is often done when viewing signal spectras of high dynamic range (such as the power-spectrum of an image), where it more generally works due to a statistical connection between power spectrum and natural images.
The second approach you can do (that is simple) is to apply a gamma-correction to your image. This gives you a simple parameter that you can tweak, and for some 2D data that is enough.
As you have pointed out yourself, it is not generally true that the logarithm (or gamma correction) will rescale your data as you want it. This is one of the reasons why Tonemapping remains an open field of research.
With this said, there are fully automatic approaches, a few are implemented in Matlab. Here is one that I have never tried myself, but supported by mathworks.