Clabel line break for label

11 views (last 30 days)
Runz Reiner
Runz Reiner on 9 Feb 2022
Commented: DGM on 25 Feb 2022
Hi everyone,
I use clabel for function contourf. If I let the labels of the individual lines be generated automatically, the line is interrupted a bit on the left and right so that the label is easy to read. However, when I enter the clabel function via 'manual', this space is not provided. This makes the label difficult to read, because this is crossed out by the line . Can this space be set separately?
Thanks.

Answers (1)

DGM
DGM on 9 Feb 2022
Edited: DGM on 9 Feb 2022
As far as I know, no. There isn't a proper way to do that in manual mode. See the answer here:
However, if your contour plot is simple (not contourf; not a contour plot over a pcolor underlay), you might have a workaround. So long as the background color is solid, you can put matting under the text objects. It's a pain, but it can be done:
x = 1:100;
y = x';
z = x+y;
[c hc] = contour(x,y,z); hold on
clabel(c,hc,'manual')
% find all the text objects and create underlays
gob = findobj(gca,'type','text');
axar = get(gca,'plotboxaspectratio');
for k = 1:numel(gob)
p = gob(k).Extent;
th = gob(k).Rotation;
R = [cosd(th) -sind(th); sind(th) cosd(th)].*[1; axar(1)];
% create point list, transform to fit
xy = [p(1)+[0 p(3) p(3) 0 0]; p(2)+[0 0 p(4) p(4) 0]].';
boxc = min(xy,[],1)+range(xy,1)/2;
xy = (R*(xy-boxc).').'+ boxc;
% create white patch, move text on top of it
hp = patch(xy(:,1),xy(:,2),'w');
hp.EdgeColor = 'none';
uistack(gob(k),'top')
end
This shows the patch extents after they've been rotated and scaled to fit. Setting the edge color makes them blend in.
This will attempt to transform the patch coordinates to correctly fit the text label for its given rotation and axes aspect ratio. If the figure window gets reshaped, the patches may be skewed problematically.
EDIT: You might be able to stretch this a bit more toward usage with contourf() or other types of configurations if you're willing to complicate things further. In this example, I'm doing contourf() with an explicit colormap matched to the number of contour levels for sake of simplicity. Instead of using a patch for matting, I'm using a fat line object. I calculate two additional points which are also transformed. These give sample points which should straddle the contour line. This allows us to know which contour level the label is on and select one of the neighboring colors from the color table.
x = 1:100;
y = x';
z = x+y;
nlevels = 16;
ct = parula(nlevels);
[c hc] = contourf(x,y,z,nlevels-1); hold on
clabel(c,hc,'manual')
colormap(ct);
% find all the text objects and create underlays
gob = findobj(gca,'type','text');
axar = get(gca,'plotboxaspectratio');
llist = get(hc,'levellist');
for k = 1:numel(gob)
p = gob(k).Extent;
th = gob(k).Rotation;
R = [cosd(th) -sind(th); sind(th) cosd(th)].*[1; axar(1)];
% find line endpoints and sample points
xy = [p(1)+[0 p(3)*[1 0.5 0.5]]; ...
[[1 1]*(p(2)+p(4)/2) p(2)+p(4)*[0.2 0.8]]].';
boxc = min(xy,[],1)+range(xy,1)/2;
xy = (R*(xy-boxc).').'+ boxc;
% sample the zdata above and below the label
samp = round(xy(3:4,:));
zsamp = [z(samp(1,1),samp(1,2)) z(samp(2,1),samp(2,2))];
[~,idx] = min(abs(mean(zsamp)-llist)); % find the contour level
levcol = ct(idx,:);
hp = plot(xy(1:2,1),xy(1:2,2),'color',levcol,'linewidth',5);
%plot(xy(3:4,1),xy(3:4,2),'wo') % mark where the level is sampled
uistack(gob(k),'top')
end
Again, show the matting and sample points for clarity. The figure on the right is the result.
  2 Comments
Runz Reiner
Runz Reiner on 25 Feb 2022
Thanks for the detailed answer
DGM
DGM on 25 Feb 2022
If you find that the answer satisfies your question, you can click Accept. That way the question gets moved to the "answered" queue, where it may be more attractive to the next person with a similar question.

Sign in to comment.

Categories

Find more on Contour Plots in Help Center and File Exchange

Tags

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!