how to do scatter plot and color code the values?
41 views (last 30 days)
Show older comments
I have 6 variables: x, y, I, theta, time, and LED (see attached the mat file). The LED is a sinusoidal signal. I want to scatter plot x in the x axis, y in the y axis, and I as a vector for each x and y. The vector I can easily be calculated as
Ivec = [cos(theta) sin(theta)]*I;
Then I want to color this Ivec according to the position of the LED signal. For each cycle of the LED signal, a shade of color will be defined. The same color shade will be repeated for the rest of the cycles present in the file.
May I know how to do this?
Thanks!
3 Comments
Adam Danz
on 11 Feb 2022
> " ...and I as a vector for each x and y"
This part is where things become unclear. The line of code provided in the question throws an error so the intentions are not clear.
> "Then I want to color this Ivec..."
This also needs some clarity. What does it mean to color a vector?
It sounds like you're looking for one of the following.
Accepted Answer
Voss
on 11 Feb 2022
S = load('matlab.mat');
Ivec = [cos(S.theta); sin(S.theta)].*S.I;
figure();
hold on
colors = flip(autumn(16),1); % specify your favorite set of colors here
N_colors = size(colors,1);
LED_thresh = linspace(min(S.LED),max(S.LED),N_colors+1);
LED_thresh([1 end]) = [-Inf Inf];
for ii = 1:size(colors,1)
idx = S.LED >= LED_thresh(ii) & S.LED < LED_thresh(ii+1);
quiver(S.x(idx),S.y(idx),Ivec(1,idx),Ivec(2,idx),0,'Color',colors(ii,:));
end
colorbar();
set(gca(), ...
'Colormap',colors, ...
'CLim',[min(S.LED) max(S.LED)], ...
'XLim',[min(S.x+Ivec(1,:)) max(S.x+Ivec(1,:))], ...
'YLim',[min(S.y+Ivec(2,:)) max(S.y+Ivec(2,:))]);
2 Comments
Adam Danz
on 11 Feb 2022
+1, looks good.
I'd set the quiver(___,scale) factor to something like 4 to decrease vector length but even still, the density prevents seeing underlying patterns.
@Anu, perhaps you could do some vector averaging to reduce the density if that's an issue.
Adam Danz
on 11 Feb 2022
My idea was to convert the LED values into index values 1:n where n is the number of colors in the colormap. This version is much slower but sets the color of each vector individually.
S = load('matlab.mat');
Ivec = [cos(S.theta); sin(S.theta)].*S.I;
figure();
hold on
nColors = 256; % integer; larger is better
colors = flip(autumn(nColors),1);
% convert LED values to color indices
LEDnorm= (S.LED - min(S.LED)) / (max(S.LED)-min(S.LED)); % (0:1)
LEDidx = round(LEDnorm * (nColors-1)) + 1; % (1:nColors)
for ii = 1:numel(S.x)
quiver(S.x(ii),S.y(ii),Ivec(1,ii),Ivec(2,ii),'off','Color',colors(LEDidx(ii),:));
end
cb = colorbar();
ylabel(cb,'LED')
set(gca(), ...
'Colormap',colors, ...
'CLim',[min(S.LED) max(S.LED)]);
More Answers (2)
Adam Danz
on 11 Feb 2022
Sounds like Les Beckham was correct. quiver() is the way to go. However, the quiver function only lets you set 1 color for all quiver arrows so you'll need to plot each one individually.
I suggest choosing (or creating) a colormap, scaling the LED values to become indices of the colormap, and then applying the colors to quiver arrows created within a loop.
If my interpretation of the task is correct, let me know where you'd like additional help, otherwise, please let us know where my interpretation goes awry.
0 Comments
William Rose
on 11 Feb 2022
@Anu,
Please do not use l (lower case L) or I (upper case i) as a variable name, because they appear identical in some fonts. Also, upper case i is likely to be confused with the identity matrix. Use L or i or something else. I am renaming your variable from upper case i to L, to avoid confusion.
load('anuData');
L=I;
You said "The vector I can easily be calculated as Ivec = [cos(theta) sin(theta)]*I;"
but this does not calculate l, since l is on the right hand side. I think you meant to say that the vector lvec can easily be calculated. Also, the statement you wrote produces an error. I think you intended do element-by-element mutiplication, with the dot-multiply operator, on the right hand side. Also, since theta and L are row vectors, you need to transpose them or use a semicolon to make two rows in lvec().
You said "I want to color this Ivec according to the position of the LED signal. For each cycle of the LED signal, a shade of color will be defined. The same color shade will be repeated for the rest of the cycles present in the file." This statement is not clear to me. If you define a color for each cycle, and you repeat the same color shade for the rest of the cycles, then all points will be the same color. I see from plotting LED versus time that LED is periodic with period T=0.5 seconds. Therefore there are 20 cycles in this recording. Perhaps you want to use a different color for each cycle. The code below uses a different color for each cycle. I also plot LED versus time, with the relevant colors, to indicate which colors correspond to which times.
lvec = [cos(theta); sin(theta)].*L; %use the dot-multiply operator
%Create a 20x3 matrix. Each row is a colorspec.
colors=[1,0,0; 1,.3,0; 1,.5,0; 1,.8,0;...
1,1,0; .8,1,0; .5,1,0; .3,1,0;...
0,1,0; 0,1,.3; 0,1,.5; 0,1,.8;...
0,1,1; 0,.8,1; 0,.5,1; 0,.3,1;...
0,0,1; .3,0,1; .5,0,1; .8,0,1];
T=0.5; %cycle duration
figure;
subplot(311), hold on
for i=1:20
plot(x(time>(i-1)*T & time<=i*T),y(time>(i-1)*T & time<=i*T),...
'Marker','*','MarkerEdgeColor',colors(i,:),'LineStyle','none');
end
xlabel('X'); ylabel('Y'); grid on
subplot(312), hold on
for i=1:20
plot(lvec(1,time>(i-1)*T & time<=i*T),lvec(2,time>(i-1)*T & time<=i*T),...
'Marker','*','MarkerEdgeColor',colors(i,:),'LineStyle','none');
end
xlabel('lvec(1)'); ylabel('lvec(2)'); grid on
subplot(313), hold on
for i=1:20
plot(time(time>(i-1)*T & time<=i*T),LED(time>(i-1)*T & time<=i*T),...
'Marker','.','MarkerEdgeColor',colors(i,:),'LineStyle','none');
end
xlabel('Time'); ylabel('LED')
Try it. Good luck!
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!