Fabio Capezzuoli
Fabio Capezzuoli

Reputation: 619

How to customize contour line labels?

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()"});

Two more or less identical plots produced by the code snippet above

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:

  1. Show labels with 2 - 3 decimal digits only.
  2. Change the label background to white.
  3. Plot labels inline with the contour line.

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

Answers (2)

Fabio Capezzuoli
Fabio Capezzuoli

Reputation: 619

Well, I used your suggestions and tinkered a bit more with my real data, to obtain this plot:

enter image description here

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

Cris Luengo
Cris Luengo

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

Related Questions