I have some data that I want to display as contour plot with logarithmic scale of the values (the matrix Z) and labelled countours. This is how I do it:
[C, h1] = contourf(X, Y, log(Z));
clabel(C,h1);
Here is my result:
My question is: how can I get the right labels on the contours? I don't want a color bar as described here.
Edit: Here is my example:
X = 1:1:20;
Y = X;
Z = zeros(size(Y));
for i = 1:size(Y,2);
Z(i, :) = 10^i;
end
[C, h1] = contourf(X, Y, Z);
clabel(C,h1);
My true data looks like this:
I can set any countour lines labels I want, but they won't be visible since my data is exponential (And by the way, the labels that are visible in this plot, are the true ones, the ones I want to get on the next plot).
Now, since my data in exponential, I have to use the logarithmic scale on the displayed values (the matrix Z) to show the data properly. Here is how I do it (maybe there is another, better way, I don't know, I haven't found anything else):
[C, h1] = contourf(X, Y, log(Z));
clabel(C,h1);
Here is how my picture looks like:
And it looks well now - you can see how my data varies. However, the labels are wrong. I can now set them to any vector you like:
Ideally, I'd like to be able to something like this:
[C, h1] = contourf(X, Y, Z, 'ZScale', 'Log');
clabel(C,h1);
and get the picture at the bottom with labels 10, 10^5, 10^10, etc.
Summing up, I need to do one of the following:
Find a way to set the logarithmic scale programmatically and let matlab worry about the isolines.
Be able to manually change the label on the isolines without moving them (new_label = 10^old_label).
A little 'Hack' that will work, although it will not be possible to keep the labels as nice as they are with a call to clabel(C,h1)
:
The first step consists in calculating the values of the contour lines. You say you want them to be placed at 1,10,...
and so on so you just need to find the first power of 10 bigger than the maximum of your data :
nextpow10Z=ceil(log10(max(Z(:))));
Now call contourf
with the vector of contour line values :
[C,h1]=contourf(X,Y,log10(Z),1:nextpow10Z);
Now instead of calling clabel(C,h1);
, we need to use another syntax of clabel that will allow us to loop trough the texts (The downgrade is that they'll be less pretty) :
tl=clabel(C);
Now if you go see the description of tl
, you'll see that it's a Data
object, containing Text
and Line
elements.
The next step consists in selecting all the elements of Type Text contained in tl
:
TextElements=findobj(tl,'Type','Text');
Finally, The last step will be to loop over these and replace the numbers N
with 1EN
:
for i=1:length(TextElements)
TextElements(i).String=strcat('1E',TextElements(i).String);
end
And voila!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With