Need help with Tooltip display?

9 views (last 30 days)
Roger Breton
Roger Breton on 29 Feb 2024
Commented: Roger Breton on 1 Mar 2024
I have a script that plots CIE Lab values in 3D:
Works great. But as you can see, the tooltip displays the XYZ value.
Instead, I would like it to display the "name of the color".
I asked chatGPT and it suggested the following code:
dcm = datacursormode(gcf);
set(dcm, 'UpdateFcn', @customDataCursor);
function txt = customDataCursor(~, event_obj)
pos = event_obj.Position;
color_name = getColorNameFromRGB(pos, colors);
txt = {['Color: ' color_name]};
end
function color_name = getColorNameFromRGB(rgb, color_struct)
% Implement logic to find the closest color name based on RGB value
% (e.g., Euclidean distance or other methods).
% Return the corresponding color name.
% For simplicity, you can use a lookup table or hard-coded mapping.
% Example:
color_name = 'PamplemousseRose'; % Replace with actual logic
end
I'm kind of lost. Upon initialization of my script, I use the following statements:
T = readtable('SICO Accents de couleur (2023 09 25).xlsx');
colorNames = T(:, 1); % Extract the color names (column 1)
labValues = T(:, 2:4); % Extract the CIE Lab values (columns 2 to 4)
Can I use a command such as "find"?

Accepted Answer

Voss
Voss on 29 Feb 2024
Here is a script you can run, along with an xlsx file containing random colors and names.
You can run it as-is, and you can also substitute your own xlsx file and see how it does with that.
% a scatter plot
figure
scatter3(200*rand(10,1)-100,200*rand(10,1)-100,100*rand(10,1),[],rand(10,1),'filled')
xlabel('b* (X)')
ylabel('a* (Y)')
zlabel('L* (Z)')
% color table
colors = readtable('colors.xlsx');
% data cursor with custom update function
dcm = datacursormode(gcf);
set(dcm, 'UpdateFcn', {@customDataCursor,colors});
% data cursor update function
function txt = customDataCursor(~, event_obj, colors)
pos = event_obj.Position;
color_name = getColorNameFromLAB(pos, colors);
txt = {['Color: ' color_name{1}]};
end
% helper function
function color_name = getColorNameFromLAB(pos, colors)
% pos is in (X,Y,Z) = (b,a,L) order and colors are in L,a,b order (I assume),
% so use colors{:,[4 3 2]}, i.e., b,a,L order to compare with pos
d2 = sum((pos-colors{:,[4 3 2]}).^2,2); % squared Euclidean distance from pos to colors
[~,idx] = min(d2); % index of minimum squared distance
color_name = colors{idx,1}; % color name at that index
end
  4 Comments
Voss
Voss on 29 Feb 2024
You're welcome! Looks good. The best code is code that: (1) works, and (2) makes sense to the programmer.
Roger Breton
Roger Breton on 1 Mar 2024
I managed to push the enveloppe a little and also display the DeltaE76 value.
See attached video (don't mind the French comments):
% Create a handle to the customDataCursor function
dcm = datacursormode(gcf);
set(dcm, 'UpdateFcn', @(src, event_obj) customDataCursor(src, event_obj, CIE_L, CIE_a, CIE_b, NomsCouleur));
function txt = customDataCursor(~, event_obj, CIE_L, CIE_a, CIE_b, NomsCouleur)
pos = event_obj.Position; % pos = 76 6 50 / 1x3 double
target_a = pos(1); % X 76
target_b = pos(2); % Y 6
target_L = pos(3); % Z 50
target_Lab = [target_L, target_a, target_b];
RGB = lab2rgb(target_Lab, 'ColorSpace','srgb', 'WhitePoint','d50');
% Check if any value is below zero
isBelowZero = RGB < 0;
isGreaterThanOne = RGB > 1;
Asterix='';
dE76=0;
% Display the result
if any(isBelowZero) || any(isGreaterThanOne)
Asterix = "*";
% Normalize RGB values to the range [0, 1]
NormRGB = max(0, min(1, RGB));
LabOut = rgb2lab(NormRGB, 'ColorSpace','srgb', 'WhitePoint','d50');
dE76 = sqrt((LabOut(1) - target_L)^2 + (LabOut(2) - target_a)^2 + (LabOut(3) - target_b)^2);
end
% Calculate Euclidean distances
distances = sqrt((CIE_L - target_L).^2 + (CIE_a - target_a).^2 + (CIE_b - target_b).^2);
[~, minIndex] = min(distances);
colorName = NomsCouleur(minIndex);
Couleur = char(colorName);
% Create a formatted string with the target L, a, and b values
% formattedCouleur = sprintf('%s (L=%.2f, a=%.2f, b=%.2f)', Couleur, target_L, target_a, target_b);
formattedCouleur = sprintf('%s (%d %d %d) %.2f', Couleur, target_L, target_a, target_b, dE76);
txt = {formattedCouleur};
end

Sign in to comment.

More Answers (0)

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Products


Release

R2023a

Community Treasure Hunt

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

Start Hunting!