Is there any way to add a set of random punctual z values labels inside the plot using a contourf x, y, z command?

6 views (last 30 days)
Is there any way to automatically add a set of random punctual z values labels inside the plot using a contourf x, y, z command (in addition to contour lines labels shown by default)?
As reference see picture attached in which I manually added text box using Paint .

Accepted Answer

Adam Danz
Adam Danz on 6 Nov 2024
Edited: Adam Danz on 6 Nov 2024
Add a set of random z value labels inside a contourf plot
This demo shows the following.
  1. Define x (vector), y (vector), and z (matrix) values for a contourf plot. (If x and y are matrices, see note below)
  2. Randomly sample the x and y vectors.
  3. Using the randomly sampled x and y values, pull out the corresponding z data to create the text labels.
  4. Use text to add labels.
See code comments for details.
rng('default') % For consistent results
% Contour data
z = peaks();
x = 1:width(z);
y = 1:height(z);
% plot contour
contourf(x,y,z,"ShowText",true)
% Sample some points within the contour plot
n = 10; % number of random labels
xRandIdx = randperm(numel(x),n);
yRandIdx = randperm(numel(y),n);
zIdx = sub2ind(size(z),yRandIdx,xRandIdx);
% Create text labels
tx = x(xRandIdx);
ty = y(yRandIdx);
tz = compose('%.2f',z(zIdx)); % 2 decimal places
text(tx,ty,tz, ...
'HorizontalAlignment','center',... % Center the label horizontally
'VerticalAlignment','middle',... % Center the label vertically
'FontSize', 8, ...
'Color',[.4 .4 .4], ...
'EdgeColor',[.4 .4 .4], ... % Show the box frame
'Margin', .2) % make the box frame tighter
colorbar() % verify results by comparing values to colorbar
If x and y are matrices, generate text inputs like this instead of the above.
randIdx = randperm(numel(x),n);
% Create text labels
tx = x(randIdx);
ty = y(randIdx);
tz = compose('%.2f',z(randIdx)); % 2 decimal places
  10 Comments
MARCO BALESTRINI
MARCO BALESTRINI on 12 Nov 2024
Edited: MARCO BALESTRINI on 12 Nov 2024
Adam I don't know how to thank you for your prompt help ❤ May I offer you a "virtual" coffe via Paypal (if it's allowed by the forum regulation)?
I confirm you that the "random" version shows only the 30% of the set "n" (that's 3 if n=10, 6 if n=20 etc etc)...but it's not a big deal...I can simply increase "n"
clc
[file, location] =uigetfile(' .xlsx');
addpath(location)
table = readtable(file);
Data=[table.n_Set, table.T_Set, table.T_GAS_TURB];
VariableName={'Speed','Torque','T_GAS_TURB'};
Datatable=array2table(Data,'VariableNames',VariableName);
ind_eff_neg=find(Datatable.T_GAS_TURB<0);
Datatable(ind_eff_neg,:)=[];
speed_val = unique(Datatable.Speed);
for i = 1 : length(speed_val)
index = find(Datatable.Speed==speed_val(i));
length_speed(i) = length(index);
clear index
end
clear i
[ MaxLenght, ~] = max(length_speed);
x = NaN(length(speed_val), MaxLenght);
y = NaN(length(speed_val), MaxLenght);
z = NaN(length(speed_val), MaxLenght);
for i = 1 : length(speed_val)
index = find(Datatable.Speed==speed_val(i));
x(i,1:length(index)) = ones(1, length(index)).*speed_val(i);
y(i,1:length(index)) = Datatable.Torque(index);
z(i,1:length(index)) = Datatable.T_GAS_TURB(index);
end
surface(x,y,z)
contourf(x,y,z,0:25:600,':', "ShowText",true,'LabelSpacing',800)
rng('default')
n = 10;
randIdx = randperm(numel(x),n);
tx = x(randIdx);
ty = y(randIdx);
tz = compose('%.0f',z(randIdx));
text(tx,ty,tz, 'HorizontalAlignment','center', 'VerticalAlignment','middle','FontSize', 10,'Color',[.2 .2 .2],'EdgeColor',[.2 .2 .2],'Margin', .5)
colorbar()
map = interp1([0; 0.35 ; 1], [0 1 0; 1 1 0; 1 0 0],linspace(0,1,100));
colormap(map)
grid on
colorbar eastoutside
clim([0 650])
title 'Temp after turbine[°C]'
xlabel 'Speed [RPM]'
ylabel 'Torque [Nm]'
ticks_x = 900:200:2300;
ticks_y = 100:200:2500;
xticks(ticks_x)
yticks(ticks_y)
Adam Danz
Adam Danz on 12 Nov 2024
@MARCO BALESTRINI, I'm glad that worked out.
I noticed that your x, y, z matrices are preallocated as NaNs. The solution I proposed selects random values within the x,y,z data. If it selects locations and x and y that have NaN values, the text label will not appear. My hunch is that your data contain ~2/3 NaN values which is why only ~1/3 of the labes are appearing.
Thanks for the coffee offer! If you ever come to MathWorks HQ, let me know. We can meet for coffee and discuss turbine effects on temperature distributions 🤓.

Sign in to comment.

More Answers (2)

Taylor
Taylor on 5 Nov 2024
You can use the text command
  5 Comments
Walter Roberson
Walter Roberson on 5 Nov 2024
Selected_X_Points = rand(1,NumberOfPoints) * (max(X_Points)-min(X_Points)) + min(X_Points);
Repeat for Y.
Then
Selected_Z_Points = interp2(X_Points, Y_Points, Z_Points, Selected_X_Points, Selected_Y_Points);
You now have random x and y coordinates and corresponding Z coordinates for the purpose of text()
text(Selected_X_Points, Selected_Y_Points, string(round(Selectted_Z_Points)))
I somehow doubt that you actuall want random points, however.
MARCO BALESTRINI
MARCO BALESTRINI on 7 Nov 2024
Edited: MARCO BALESTRINI on 7 Nov 2024
Yes, I do want random points, because it's all aimed to help the plot readibility.
Anyway I can't understand your hint:
(max(X_Points)-min(X_Points)) + min(X_Points)

Sign in to comment.


Umar
Umar on 5 Nov 2024

Hi @MARCO BALESTRINI ,

To achieve your goal of adding labels that display the actual values of the Z variable at certain points on a contourf plot in MATLAB, you can use the ShowText option in combination with the LabelFormat property. Here is a step-by-step approach, start by defining your X, Y, and Z matrices. For example, using a mathematical function like peaks can serve as a good starting point:

   [X, Y, Z] = peaks(50);  % Create sample data

Use the contourf function to create the filled contour plot. You can specify levels if you want to control where the labels appear. For instance, to display contours at specified levels while showing text labels:

   contourf(X, Y, Z, 'ShowText', 'on');

If you want to format the labels (for example, to show one decimal place), you can use the LabelFormat property. As of R2022b, this allows you to define how labels are displayed:

   contourf(X, Y, Z, 'ShowText', true, 'LabelFormat', '%0.1f');

Here is complete example that combines all these steps:

   % Create sample data
   [X, Y, Z] = peaks(50);
   % Create filled contour plot with labeled contours
   contourf(X, Y, Z, 'ShowText', 'on', 'LabelFormat', '%0.1f');
   colorbar;  % Optional: adds a color bar for reference
   title('Filled Contour Plot with Labels');
   xlabel('X-axis');
   ylabel('Y-axis');

Now, if you are interested in showing labels in different units or applying custom formatting (like converting meters to feet), you can define a custom labeling function and pass it to LabelFormat. Here is an example function:

   function labels = mylabelfun(vals)
       feetPerMeter = 3.28084;
       feet = round(vals * feetPerMeter);
       labels = vals + " m (" + feet + " ft)";
       labels(vals == 0) = "0 m";
   end
   % Usage in contourf
   contourf(X, Y, Z, 'ShowText', true, 'LabelFormat', @mylabelfun);

Please see attached.

You can further enhance your plot's aesthetics by adjusting properties such as color maps (`colormap`), transparency (`FaceAlpha`), and line widths (`LineWidth`).

Hope this helps.

Please let me know if you have any further questions.

Community Treasure Hunt

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

Start Hunting!