Plotting different colored line based on condition(s)

91 次查看(过去 30 天)
Hello: I am attempting to plot a line that changes colors (between red and green) based upon the value of the data. For example, if I have x=1:1:5 and corresponding y=[-2,-1,1,2,3], I would like the plot to have a red line when y is negative and a green line when y is positive and have a corresponding legend to denote this. P.S. my actual data series is much longer than (5) values so a looping code would be preferable.

采纳的回答

Chad Greene
Chad Greene 2020-10-6
编辑:Chad Greene 2020-10-6
What if you create two lines and plot them separately?
x = 0:1000;
y = sind(x);
% duplicate:
y_red = y;
y_red(y>0) = NaN;
y_green = y;
y_green(y<0) = NaN;
figure
plot(x,y_red,'r','linewidth',2)
hold on
plot(x,y_green,'g','linewidth',2)
  2 个评论
Adam Danz
Adam Danz 2020-10-6
编辑:Adam Danz 2020-10-6
This is the best method when the x values are already known at y=0. It's simple, effective, and quick. But if the x coordinates are not known when y=0, you'll need to compute them and insert them into the (x,y) vectors.
For example, try approach solution when x = 22:45:1080.

请先登录,再进行评论。

更多回答(1 个)

Adam Danz
Adam Danz 2020-10-6
编辑:Adam Danz 2020-10-6
A line object can only have 1 color. To change the color of values above and below y=0 you have to break up your line into segments. This is relatively easy if you already have y-coordinates at (or very close to) zero and can be solved by simple logical indexing.
However if line segments pass through y=0 you must compute the x-coordinates where y equals 0 and insert those coordinates into your (x,y) vectors.
Here's a demo that steps through that process.
% Define coarse (x,y) coordinates that pass through y=0
x=1:1:15;
y=[-2,-1,1,2,3];
y = [y,fliplr(y),y];
% Plot the original data
figure()
plot(x,y,'b-o','LineWidth',2)
yline(0)
% Get the index of each coordinate just prior to passing y=0 (startSegIdx)
signDiff = [0,diff(sign(y(:)'))];
startSegIdx = unique([find(signDiff(:)'==2)-1, find(signDiff(:)'==-2)-1])
startSegIdx = 1×3
2 8 12
% For each segment that passes through y=0, compute equation
% of the line and solve for y=0
x0 = nan(size(startSegIdx));
for i = 1:numel(startSegIdx)
coeffs = polyfit(x(startSegIdx(i)+[0,1]), y(startSegIdx(i)+[0,1]), 1);
x0(i) = -coeffs(2)/coeffs(1);
end
% (x0,y0) are the y== crossing points. Add those points to the plot
% to check for accuracy
figure()
plot(x,y,'b-o','LineWidth',2)
yline(0)
hold on
plot(x0,zeros(size(x0)),'m*','MarkerSize', 12,'LineWidth',2)
% Insert the new (x0,y0) coordinates in the correct incides of (x,y)
repNum = ones(size(x));
repNum(startSegIdx) = 2;
xNew = repelem(x(:).',1,repNum(:)');
xNew(startSegIdx + (1:numel(startSegIdx))) = x0;
yNew = repelem(y(:).',1,repNum(:)');
yNew(startSegIdx + (1:numel(startSegIdx))) = 0;
% Plot the new line to make sure it matches the old one, plus the 0-crossings
figure()
plot(x,y,'b-o','LineWidth',2)
yline(0)
hold on
plot(x0,zeros(size(x0)),'m*','MarkerSize', 12,'LineWidth',2)
plot(xNew, yNew, 'r:o', 'LineWidth', 1, 'MarkerSize', 16)
% Break up the (xNew,yNew) line into segments below/above y=0
% There will be 1 segment for each time it crosses y=0
% 1. Duplicate values at x=0
segmentSub = unique(find(sign(yNew(:)')==0));
repNum2 = ones(size(xNew));
repNum2(segmentSub) = 2;
xSeg = repelem(xNew, 1, repNum2);
ySeg = repelem(yNew, 1, repNum2);
% create a grouping variable for each element of (xSeg, ySeg) that identifies its segment.
segmentSub2 = [segmentSub + (0:numel(segmentSub)-1), numel(xSeg)];
group = repelem(1:numel(segmentSub2),diff([0,segmentSub2]));
% Plot the line segments
figure()
hold on % important
h = splitapply(@(x,y)plot(x,y,'-o','LineWidth',1),xSeg,ySeg,group);
% Color segment based on the sign of y values
isPositive = arrayfun(@(h)any(h.YData > 0),h);
set(h(isPositive), 'Color', 'g')
set(h(~isPositive), 'Color', 'r')
% add ref line
yline(0)

类别

Help CenterFile Exchange 中查找有关 Annotations 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by