How could I display a "circle at the bottom of the figure? And color it along the way? To show Hue angles?
13 views (last 30 days)
Show older comments
Crazy idea. I know Matlab is calling OpenGL under the hood but I would not know how to go about adding these two pieces of geometric elements to my chart. What follows is a "mock-up", to show what I'm trying to achieve :
You have my 3D figure, showing a custom datatip. What I would like to add is a "3D plot" (I guess?) that sits at the bottom of the chart, I get using some kind of colormap, to simulate a continuous drawing? The idea is to represent "Hue angle" on this chart, To show it through a "color wheel" and some kind of "black line" drawn along the hue angle, to show the students how to interpret visually the notion that color can have an "angle".
0 Comments
Accepted Answer
DGM
on 5 Mar 2022
Edited: DGM
on 5 Mar 2022
The problem that I'm seeing with the answers so far is that they're not going to be projected correctly into the color space in use.
If you do something using a plain HSV sweep, you'll get something that aligns like this. I stacked the ring on top so it's easy to tell that it's misaligned.
Obviously, the projection of the corners of the RGB cube are no longer spaced by equal angles in LAB. You need to actually project that color sweep into the space you're using.
This is an example
% parameters
npoints = 1000;
radius = 100;
% get a cyclic rgb color map
CTrgb = hsv(npoints);
% project it into the desired space, set radius to a constant
CTlab = rgb2lab(CTrgb);
[th,~] = cart2pol(CTlab(:,2),CTlab(:,3));
[CTa CTb] = pol2cart(th,radius);
% put something relevant in the axes
% just to show that the alignment is correct
csview('lab'); % THIS IS MIMT
xlim([-150 150])
ylim([-150 150])
hold on;
% plot a dense scatter to make the hue ring
scatter(CTa,CTb,30,CTrgb,'filled');
Note that I used MIMT csview() for the example, but it's not at all necessary for your task. If that's something you want to use, for anything, let me know. The version that's current in MIMT is kind of janky garbage. I rewrote it last week but haven't uploaded it yet.
7 Comments
DGM
on 6 Mar 2022
No problem.
By the way, did you catch the late response I made on your other post about trying to draw slice boundaries?
If you want to stick with the way you're doing it, that's fine. I was just a bit overeager to share, since I don't know of anything that does what maxchroma() can do so succinctly.
More Answers (5)
Image Analyst
on 3 Mar 2022
Perhaps you can adapt my attached demo.
6 Comments
Les Beckham
on 4 Mar 2022
@Image Analyst provided a comment here that shows what you can achieve using the surface command. I see no reason that this approach wouldn't at least get you close to what you want to do. Just define the x/y/z coordinates of your circle and make the color vary with the angle as you go around the circle.
Les Beckham
on 4 Mar 2022
I decided to experiment with it and came up with this based on his example.
See if it is close to what you want.
r = 50;
rho = linspace(0, 2*pi, 1920); % HDTV resolution.
x = cos(rho) * r;
y = sin(rho) * r;
z = zeros(size(x));
lineColor = rho(1:2:end); % This is the color, it varies with rho in this case.
lineColor = [lineColor flip(lineColor)];
% Plot the line with width 8 so we can see the colors well.
surface([x;x], [y;y], [z;z], [lineColor;lineColor],...
'FaceColor', 'no',...
'EdgeColor', 'interp',...
'LineWidth', 8);
grid on;
axis equal
view(16.5, 25)
Image Analyst
on 4 Mar 2022
Edited: Image Analyst
on 4 Mar 2022
You can make a colored circle by plotting markers:
numPoints = 1000;
angle = linspace(0, 360, numPoints);
x = sind(angle);
y = cosd(angle);
colors = hsv(numPoints);
for k = 1 : numPoints
plot(x(k), y(k), '.', 'MarkerSize', 20, 'Color', colors(k,:));
hold on;
end
grid on;
xlabel('x');
ylabel('y');
axis equal
3 Comments
Image Analyst
on 5 Mar 2022
Yes, essentially colors is an N b y 2 array (colormap) and you can put whatever color you want into each row to get the colors to be in the proper order.
Roger Breton
on 7 Mar 2022
3 Comments
DGM
on 9 Mar 2022
For what it's worth, the hue ring part can probably be reduced to a literal CT and point list if you want simplicity and speed. Attached is a .mat file containing a uniform 200-point ring. My assumption about how much the interpolation would cost for a uniform ring was wrong. The reduction in point count is significant enough that that it's actually faster. Using the precalculated result is faster yet, and it's concise:
S = load('huering.mat');
% put something relevant in the axes
% just to show that the alignment is correct
csview('lab');
xlim([-150 150])
ylim([-150 150])
hold on;
% plot a scatter to make the hue ring
scatter(S.CTa,S.CTb,30,S.newCTrgb,'filled'); hold on
That makes for a relatively solid ring with only 200 points.
This is how I calculated the points and new CT:
% parameters
npoints = 200;
radius = 100;
% get a cyclic rgb color map
CTrgb = hsv(npoints);
CTlch = rgb2lch(ct2im(CTrgb),'lab');
H = rad2deg(unwrap(deg2rad(CTlch(:,:,3))));
newH = linspace(H(1),H(end),npoints).';
newCTrgb = interp1(H,CTrgb,newH);
% get A,B coordinates
CTa = radius*cosd(newH);
CTb = radius*sind(newH);
%save('huering.mat','newCTrgb','CTa','CTb');
I cheated and used MIMT rgb2lch(), but that can be done with rgb2lab() and polar conversions.
Roger Breton
on 9 Mar 2022
2 Comments
DGM
on 9 Mar 2022
Is this something you might think about releasing on the File Exchange when it's all done?
See Also
Categories
Find more on Data Distribution Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!