logarithmic range colorbar imagesc

In my code I use the function imagesc; plotting (X,Y,Z) data in which: X vector distance, Y vector time, and my data Z = Z(X,Y) a matrix. In my plot the 80% of the image has one color, because the change of Z data occurred only in a specific area of X-Y. I need to change the colorbar range, from a normal to a logarithmic one, to improve visual the range of the change of my output data through time along the distance X. Please, if anyone knows how to solve this issue let me know.

Answers (3)

You can use my cptcmap.m function to create a logarithmically-spaced colormap (and corresponding colorbar).
However, keep in mind that Matlab requires linearly-spaced color intervals in its colormaps, so my function achieves uneven color intervals by replicating certain colors many times. You may not get the results you want if your values span too many orders of magnitude. For example, to create a colormap where one color spans only 1/1000th of the color range, you need a 1000-color colormap. I believe some systems (Windows?) may limit you to 256 colors in a colormap.
However, if your values span a relatively small range, the following example should work:
x = peaks(200);
x = (x - min(x(:)))./(max(x(:))-min(x(:)));
x = x*9 + 1;
tk = logspace(0,1,10);
cmap = jet(9);
ctable = [tk(1:end-1)' cmap*255 tk(2:end)' cmap*255];
save mycol.cpt ctable -ascii;
ax = axes;
imagesc(x);
cptcmap('mycol', 'mapping', 'direct');
cptcbar(gca, 'mycol', 'eastoutside', false);

4 Comments

Kelly, thank you for your help, I am working on your script right now. The range of the data is from: -100 until +100. in a small area the values play to the 90% of the range; 80% is near to zero. So, I need to modify your script. I though could be more easy; seems not. Do you suggest to use another function, as contourf ? with many contours? I use imagesc cause the output is smoothed and represent better the data that I need to compare with similar images.
What are your desired color intervals? Contour plots might be a better option, but that will depend on the color intervals that you're trying to resolve.
To modify my example, you'll need to start with your desired color palette table. Here's a description of the format. It's basically six columns, with one row per color interval: lower-value, RGB low (on 0-255 scale), upper-value, RGB hi.
So, for example:
ctable = [...
-10.0 40 9 218 -5.0 40 9 218
-5.0 36 77 255 -3.0 36 77 255
-3.0 60 161 255 -2.0 60 161 255
-2.0 113 218 255 -1.0 113 218 255
-1.0 171 250 255 -0.5 171 250 255
-0.5 226 255 255 0.0 226 255 255
0.0 255 255 190 0.5 255 255 190
0.5 255 223 153 1.0 255 223 153
1.0 255 174 113 2.0 255 174 113
2.0 249 109 93 3.0 249 109 93
3.0 218 36 48 5.0 218 36 48
5.0 164 0 32 10.0 164 0 32];
creates a color palette going from blue to red but with values closer together near 0 (it's the UKM_hadcrut_10 one shown on this page.)
If you change the values in the columns 1 and 4 by a factor of 10, they might work for your purposes.
Great tool and great solution!
Good solution! Love from China

Sign in to comment.

Image Analyst
Image Analyst on 9 Nov 2015
Use caxis() to specify what image values the colorbar should start at and stop at.

1 Comment

I use caxis, I need a logarithmic range of colors related to the range of my data

Sign in to comment.

Adam
Adam on 9 Nov 2015
Edited: Adam on 9 Nov 2015
I would normally solve this problem simply by taking the logarithm of my data and plotting that if simply constraining the colourbar range is not enough.
I'm not sure there is a simply way to show a non-linear colourmap without creating your own colourmap. The mapping is always linear as far as I am aware which would imply you can either make your data logarithmic or you can define a logarithmic colourmap yourself. I don't know how to do the latter off-hand though.

6 Comments

I can't make the data logarithmic; tried to much NAN values. The range is from -100 to 100 but with many close to zero. logarithmic colourmap is what I want.; thank you for trying.
Can you attach your data so we can try things?
Can you attach your data so we can try things?
K.
K. on 10 Nov 2015
Edited: K. on 10 Nov 2015
Yes, here is the X - vector distance, Y - vector time , Z1 matrix data ( I include also Z2 )
<https://mega.nz/#!dsBhVAxC!c4i1kCJZV54NBXEafe45Xbt7k7XIJfpntZAV7kbVuOs>
or
<https://mega.nz/#!Z1RU3BwC!2NiOQLWt8udPtAbh38TeCP6stVr6CfMmXIIcfPsVbfg zip>
I don't really want to download data from a random site (you can attach to a comment here), but for general data in that range...
Having data from -100 to 100 is not a problem. You can abs the negative data, take its logarithm and then reintroduce the sign afterwards - e.g.
signs = sign( data );
logData = signs .* log( abs( data ) );
I'm not sure what the issue with NaNs is either. If you have NaNs in your data then log( NaN ) is also NaN anyway so you don't lose anything that way from what you started with.
0s would be a problem but you can easily use logical indexing to reinsert all the 0s into your log data in the same places they were in the original data.
this is not a random site! you asked for the data and I sent it to you! is my MEGA box!

Sign in to comment.

Products

Asked:

K.
on 9 Nov 2015

Commented:

on 12 Jul 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!