Need help with Tooltip display?

11 Ansichten (letzte 30 Tage)
Roger Breton
Roger Breton am 29 Feb. 2024
Kommentiert: Roger Breton am 1 Mär. 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"?

Akzeptierte Antwort

Voss
Voss am 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 Kommentare
Voss
Voss am 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 am 1 Mär. 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

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte


Version

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by