2
votes

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?

2
"As you can see, the data....." and you put it all in here expecting us to visually find the semi-colons and count? Put the effort in, and display your data in question. I dont read further then just seeing the raw data and your first line of english.Stefan Karlsson
If you had used your effort of writing this comment for reading a little bit further you could see that there are in fact images attached that save you from reading the data as you wish..The only thing is that they are hidden in a link, which I cannot do anything about until I have enough reputation. I don't think it is so fair to give me a minus for just that and does not help me in gaining enough reputation to post images either. I would appreciate if you undo it, so hopefully next time I cán post clear images.Phoneheads
There, that looks better, so upvoted.Stefan Karlsson
Consider accepting my answer below. This was a good question, and the answer can benefit the community.Stefan Karlsson

2 Answers

0
votes

You could plot the log of your data instead, like

surf(log(test))
caxis(log([min(test(:)) max(test(:))]));
colorbar_array = linspace(log(min(test(:))), log(max(test(:))), 5);
colorbar('FontSize',11,'YTick',colorbar_array,'YTickLabel',exp(colorbar_array));

Edit: you will still need to fiddle around with the colormap editor, to get the differences at the upper limit of the data range resolved (yellow region).

0
votes

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.