Reputation: 619
I would like to visualize a function of two variables in a contour plot using Octave, and to put customized line labels on it.
Building on the Octave documentation, I wrote:
clf;
colormap ("default");
[x, y, z] = peaks ();
subplot(2,1,1);
contour (x, y, z,'showtext', 'on');
title ({"contour() plot, showtext on"; "Z = peaks()"});
subplot(2,1,2);
[ctr, h] = contour (x, y, z);
cll = clabel(ctr, h, 'backgroundcolor',[1 1 1]);
title ({"contour() plot, using clabel()"; "Z = peaks()"});
Which produces two only marginally (if at all) different plots. The labels are there, but don't look nice at all; I need better quality for this project.
What I would like to do is, in order of priority:
From Octave documentation it appears that the label values are stored in "userdata"
, but it's not of much help because:
>> get(cll, "userdata")
ans =
{
[1,1] = 6.7459
[2,1] = 5.4167
[3,1] = 5.4167
[4,1] = 4.0874
[5,1] = 4.0874
[6,1] = 2.7581
[7,1] = 2.7581
[8,1] = 2.7581
[9,1] = 2.7581
[10,1] = 1.4289
[11,1] = 1.4289
[12,1] = 1.4289
[13,1] = 1.4289
[14,1] = 0.099636
[15,1] = 0.099636
[16,1] = 0.099636
[17,1] = 0.099636
[18,1] = 0.099636
[19,1] = 0.099636
[20,1] = -1.2296
[21,1] = -1.2296
[22,1] = -1.2296
[23,1] = -1.2296
[24,1] = -2.5589
[25,1] = -2.5589
[26,1] = -2.5589
[27,1] = -3.8881
[28,1] = -5.2174
I am not sure how the number of repetitions for a value is determined. I'd appreciate help on this matter.
Upvotes: 2
Views: 1713
Reputation: 619
Well, I used your suggestions and tinkered a bit more with my real data, to obtain this plot:
Which is good for my needs, except for that lonely "0.09" in the left part of the plot. That shouldn't be there but I cannot figure why it appears.
set(gca,'children',flip(get(gca,'children')))
does not work tho.
Upvotes: 1
Reputation: 60564
To show labels with fewer digits, the best way is to manually specify at which z-values to draw contour lines (see explanation in the documentation to contourc
):
colormap('default');
[x, y, z] = peaks();
vn = ceil(min(z(:))):floor(max(z(:))); % list of all integer values within range of data
contour(x, y, z, vn, 'showtext', 'on');
title({"contour() plot, showtext on"; "Z = peaks()"});
You can also specify which contour lines to put labels on:
colormap('default');
[x, y, z] = peaks();
vn = ceil(min(z(:))):floor(max(z(:)));
[ctr, h] = contour(x, y, z, vn);
clabel(ctr, h, vn(1:2:end), 'backgroundcolor',[1 1 1]);
title({"contour() plot, showtext on"; "Z = peaks()"});
I don't have Octave here, but the 'background color'
argument should do its thing. It is possible that the lines are drawn over the text, rather than the text over the lines. MATLAB has a command uistack
to force drawing order, but this does not seem to exist in Octave. There, one possibility might be to change the order of the children of the axis object:
set(gca,'children',flip(get(gca,'children')))
(Note: MATLAB's contour
does a better job of picking nice contour levels, and it also by default interrupts the line where the labels are, so lines and text don't intersect.)
Upvotes: 1