logarithmic range colorbar imagesc
Show older comments
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)
Kelly Kearney
on 9 Nov 2015
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
K.
on 9 Nov 2015
Kelly Kearney
on 9 Nov 2015
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.
Andrea Manconi
on 5 Nov 2019
Great tool and great solution!
WANG minhao
on 12 Jul 2023
Good solution! Love from China
Image Analyst
on 9 Nov 2015
0 votes
Use caxis() to specify what image values the colorbar should start at and stop at.
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
K.
on 9 Nov 2015
Image Analyst
on 9 Nov 2015
Can you attach your data so we can try things?
Image Analyst
on 9 Nov 2015
Can you attach your data so we can try things?
Adam
on 10 Nov 2015
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.
K.
on 10 Nov 2015
Categories
Find more on Blue in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!