How to vary the color of a dynamic line?

9 views (last 30 days)
Hello,
I am currently doing a program that can show the live trajectory of a car, based on recorded data of an RC car (here I created values in an Excel file). This trajectory is a line and its color is supposed to change with the velocity of the car (blue for the lowest speeds, red for the highest ones).
I have a "for" loop where the position of the car and of its trajectory is updated and I tried to include the change of color in the "set". In order to do that, I wrote an RGB code that varies with the speed vector "v".
The problem is that there is a change of the color of the whole trajectory, not just the last updated section.
Thank you in advance for your help.
(I have Matlab R2018b)

Accepted Answer

Adam Danz
Adam Danz on 2 Jul 2019
Edited: Adam Danz on 26 Aug 2020
There are a few ways around this (see this answer for demos). One way is to plot the line in segments such that each segment can be controlled individually and then, within a loop, make each segement visible. Some alternatives are to use patch() or fill() but then you're no longer working with lines.
See inline comments for details.
% Reshape lines to segments
% Assumes x and y are *column* vectors
% Example: x = (1:.1:5)'; y = x.^2
xseg = [x(1:end-1),x(2:end)];
yseg = [y(1:end-1),y(2:end)];
% Plot all line segments (invisible for now unless you remove 'visible','off')
h = plot(xseg',yseg','-','LineWidth',4,'Visible','Off');
axis equal;
xlim([min(x) max(x)]);
ylim([min(y) max(y)]);
% Set all line segment colors (FOR DATA PROVIDED BY OP)
% segColors = [v./max(v),zeros(size(v)),1-v./max(v)];
% set(h, {'Color'}, mat2cell(segColors,ones(size(v)),3))
% Set all line segment colors (GENERAL SOLUTION)
segColors = jet(size(xseg,1)); % Choose a colormap
set(h, {'Color'}, mat2cell(segColors,ones(size(xseg,1),1),3))
% Make segements visible in loop
% for n = 1:numel(t)-1
% pause(.05)
% set(h(n),'Visible', 'on')
% drawnow();
% end
% Or make it all visible at once
set(h, 'Visible', 'on')

More Answers (2)

Jon
Jon on 2 Jul 2019
I was just trying to code up an example, but when I finished I saw you already had an answer from Adam. My solultion used a similar approach to the answer just given by Adam.That is plot line segments and vary the color of each segment. In case it is useful I have put my code here, which might give you some alternatives for implementing the details:
% assign some parameters
numColors = 256; % resolution of color map
numPoints = 100; % number of points on trajectory
tFinal = 100; % final time
% assign color map
colorMap = jet(numColors)
% make up a trajectory and associated velocity value
% no physical meaning here, just to test the program
t = linspace(0,tFinal,numPoints);
x = 3*t.^2;
y = 5*t.^3;
d = sqrt(x.^2 + y.^2);
v = [0,diff(d)]/(tFinal/numPoints); % approximate velocity
vMax = max(v); % save maximum velocity for scaling colors
% plot the data with color change
% accomplish this by plotting individual segments of trajectory each with
% their own color according to the average velocity of the segment
figure % make a new figure
for k = 1:numPoints-1
% calculate average velocity for this segment
vAvg = (v(k) + v(k+1))/2;
% look up color for current velocity
idx = ceil(vAvg/vMax*numColors) % normalize by maximum velocity
color = colorMap(idx,:);
plot([x(k),x(k+1)],[y(k),y(k+1)],'-','Color',color)
hold on % keep the previously plotted segments
end
hold off % back to normal
xlabel('X position')
ylabel('y position')
colorchange.jpg

Alexandre Piot
Alexandre Piot on 2 Jul 2019
Thank you very much Adam and Jon for your answers, it works perfectly!
I put the final code with the animation of the car below, I hope it will help other people (if you want to use it you have also to download the excel file attached in my first message).
clear, close, clc
%% Download and organize input data
% Raw input data
input_data = xlsread('input_values.xlsx');
t = input_data(:,1);
x = input_data(:,2);
y = input_data(:,3);
z = zeros(size(t));
% Matrix of the crossing points for the car (required for makehgtform)
pt = cat(2,x,y,z);
% Calculation of a speed vector
v = [sqrt(x(2)^2+y(2)^2)/t(2)];
for m = 2:numel(t)-1
v = cat(1,v,(sqrt(x(m+1)^2+y(m+1)^2)-sqrt(x(m)^2+y(m)^2))/(t(m+1)-t(m)));
end
% Calculation of the angle (angle between the tangent and the y-axis)
alph = [acos(((x(2)-x(1))*0+(y(2)-y(1))*1)/(norm([x(2)-x(1) y(2)-y(1)])*norm([1 0])))];
for m = 2:numel(t)-1
alph = cat(1,alph,acos(((x(m)-x(m-1))*0+(y(m)-y(m-1))*1)/(norm([x(m)-x(m-1) y(m)-y(m-1)])*norm([1 0]))));
end
% Geometry of the vehicle
wb = 4;
wt = 2.5;
%% Realization of the animation
% Reshape lines to segments
% Assumes x and y are column vectors
xseg = [x(1:end-1),x(2:end)];
yseg = [y(1:end-1),y(2:end)];
% Plot all line segments (invisible!)
h = plot(xseg',yseg','-','LineWidth',2,'Visible','Off');
axis equal;
xlim([min(x) max(x)]);
ylim([min(y) max(y)]);
%Initialize the rectangle position (the car)
xr = [x(1)-wt/2,x(1)-wt/2,x(1)+wt/2,x(1)+wt/2];
yr = [y(1)-wb/2,y(1)+wb/2,y(1)+wb/2,y(1)-wb/2];
r = hgtransform;
patch('XData',xr,'YData',yr,'FaceColor','black','Parent',r);
% Set all line segment colors
segColors = [v./max(v),zeros(size(v)),1-v./max(v)];
set(h, {'Color'}, mat2cell(segColors,ones(size(v)),3))
% Make segements visible in loop
for n = 1:numel(t)-1
pause(t(n+1)-t(n))
set(h(n),'Visible', 'on')
r.Matrix = makehgtform('translate',pt(n+1,:),'zrotate',-alph(n));
drawnow();
end
  4 Comments
Adam
Adam on 3 Jul 2019
Beware though that plotting a line as segments tends to have an adverse affect on performance if you have too many segments. Ideally 1 graphics object containing your whole 'line' is far more performant than 1000 graphics objects making up a line. If it isn't a problem for your usage though then no need to worry about it, just something to be aware of if your data size gets bigger.
Alexandre Piot
Alexandre Piot on 3 Jul 2019
The goal is too have a dynamic display of the trajectory while the information comes from the IMU on the RC car, that's why I need such a segmentation of the curve. I don't know if it's possible to have 1 graphic object which would dynamic and that would update in real time.

Sign in to comment.

Categories

Find more on Animation 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!