Plotting different colored line based on condition(s)

조회 수: 136 (최근 30일)
Nicholas Bragaia
Nicholas Bragaia 2020년 10월 6일
편집: Adam Danz 2020년 10월 6일
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
Nicholas Bragaia
Nicholas Bragaia 2020년 10월 6일
Thank you, Chad. This method works nicely.
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